diff --git a/git/__init__.py b/git/__init__.py index ca5bed7a3..a13030456 100644 --- a/git/__init__.py +++ b/git/__init__.py @@ -5,7 +5,7 @@ # @PydevCodeAnalysisIgnore -__all__ = [ # noqa: F405 +__all__ = [ "Actor", "AmbiguousObjectName", "BadName", @@ -88,32 +88,112 @@ __version__ = "git" -from typing import List, Optional, Sequence, Tuple, Union, TYPE_CHECKING +from typing import List, Optional, Sequence, TYPE_CHECKING, Tuple, Union from gitdb.util import to_hex_sha -from git.exc import * # noqa: F403 # @NoMove @IgnorePep8 + +from git.exc import ( + AmbiguousObjectName, + BadName, + BadObject, + BadObjectType, + CacheError, + CheckoutError, + CommandError, + GitCommandError, + GitCommandNotFound, + GitError, + HookExecutionError, + InvalidDBRoot, + InvalidGitRepositoryError, + NoSuchPathError, + ODBError, + ParseError, + RepositoryDirtyError, + UnmergedEntriesError, + UnsafeOptionError, + UnsafeProtocolError, + UnsupportedOperation, + WorkTreeRepositoryUnsupported, +) from git.types import PathLike try: - from git.compat import safe_decode # @NoMove @IgnorePep8 - from git.config import GitConfigParser # @NoMove @IgnorePep8 - from git.objects import * # noqa: F403 # @NoMove @IgnorePep8 - from git.refs import * # noqa: F403 # @NoMove @IgnorePep8 - from git.diff import * # noqa: F403 # @NoMove @IgnorePep8 - from git.db import * # noqa: F403 # @NoMove @IgnorePep8 - from git.cmd import Git # @NoMove @IgnorePep8 - from git.repo import Repo # @NoMove @IgnorePep8 - from git.remote import * # noqa: F403 # @NoMove @IgnorePep8 - from git.index import * # noqa: F403 # @NoMove @IgnorePep8 - from git.util import ( # @NoMove @IgnorePep8 - LockFile, + from git.compat import safe_decode # @NoMove + from git.config import GitConfigParser # @NoMove + from git.objects import ( # @NoMove + Blob, + Commit, + IndexObject, + Object, + RootModule, + RootUpdateProgress, + Submodule, + TagObject, + Tree, + TreeModifier, + UpdateProgress, + ) + from git.refs import ( # @NoMove + HEAD, + Head, + RefLog, + RefLogEntry, + Reference, + RemoteReference, + SymbolicReference, + Tag, + TagReference, + head, # noqa: F401 # Nonpublic. May disappear! Use git.refs.head. + log, # noqa: F401 # Nonpublic. May disappear! Use git.refs.log. + reference, # noqa: F401 # Nonpublic. May disappear! Use git.refs.reference. + symbolic, # noqa: F401 # Nonpublic. May disappear! Use git.refs.symbolic. + tag, # noqa: F401 # Nonpublic. May disappear! Use git.refs.tag. + ) + from git.diff import ( # @NoMove + INDEX, + NULL_TREE, + Diff, + DiffConstants, + DiffIndex, + Diffable, + ) + from git.db import GitCmdObjectDB, GitDB # @NoMove + from git.cmd import Git # @NoMove + from git.repo import Repo # @NoMove + from git.remote import FetchInfo, PushInfo, Remote, RemoteProgress # @NoMove + from git.index import ( # @NoMove + BaseIndexEntry, + BlobFilter, + CheckoutError, + IndexEntry, + IndexFile, + StageType, + base, # noqa: F401 # Nonpublic. May disappear! Use git.index.base. + fun, # noqa: F401 # Nonpublic. May disappear! Use git.index.fun. + typ, # noqa: F401 # Nonpublic. May disappear! Use git.index.typ. + # + # NOTE: The expression `git.util` evaluates to git.index.util, and the import + # `from git import util` imports git.index.util, NOT git.util. It may not be + # feasible to change this until the next major version, to avoid breaking code + # inadvertently relying on it. If git.index.util really is what you want, use or + # import from that name, to avoid confusion. To use the "real" git.util module, + # write `from git.util import ...`, or access it as `sys.modules["git.util"]`. + # (This differs from other historical indirect-submodule imports that are + # unambiguously nonpublic and are subject to immediate removal. Here, the public + # git.util module, even though different, makes it less discoverable that the + # expression `git.util` refers to a non-public attribute of the git module.) + util, # noqa: F401 + ) + from git.util import ( # @NoMove + Actor, BlockingLockFile, + LockFile, Stats, - Actor, remove_password_if_present, rmtree, ) -except GitError as _exc: # noqa: F405 +except GitError as _exc: raise ImportError("%s: %s" % (_exc.__class__.__name__, _exc)) from _exc # { Initialize git executable path diff --git a/git/cmd.py b/git/cmd.py index 2862b1600..03e5d7ffc 100644 --- a/git/cmd.py +++ b/git/cmd.py @@ -5,18 +5,20 @@ from __future__ import annotations -import re +__all__ = ["Git"] + import contextlib import io import itertools import logging import os +import re import signal -from subprocess import Popen, PIPE, DEVNULL import subprocess +from subprocess import DEVNULL, PIPE, Popen import sys -import threading from textwrap import dedent +import threading from git.compat import defenc, force_bytes, safe_decode from git.exc import ( @@ -57,12 +59,11 @@ overload, ) -from git.types import PathLike, Literal, TBD +from git.types import Literal, PathLike, TBD if TYPE_CHECKING: - from git.repo.base import Repo from git.diff import DiffIndex - + from git.repo.base import Repo # --------------------------------------------------------------------------------- @@ -84,8 +85,6 @@ _logger = logging.getLogger(__name__) -__all__ = ("Git",) - # ============================================================================== ## @name Utilities diff --git a/git/compat.py b/git/compat.py index 6f5376c9d..4ede8c985 100644 --- a/git/compat.py +++ b/git/compat.py @@ -14,18 +14,18 @@ import os import sys -from gitdb.utils.encoding import force_bytes, force_text # noqa: F401 # @UnusedImport +from gitdb.utils.encoding import force_bytes, force_text # noqa: F401 # typing -------------------------------------------------------------------- -from typing import ( # noqa: F401 - Any, +from typing import ( + Any, # noqa: F401 AnyStr, - Dict, - IO, + Dict, # noqa: F401 + IO, # noqa: F401 Optional, - Tuple, - Type, + Tuple, # noqa: F401 + Type, # noqa: F401 Union, overload, ) diff --git a/git/config.py b/git/config.py index f74d290cc..3ce9b123f 100644 --- a/git/config.py +++ b/git/config.py @@ -5,6 +5,8 @@ """Parser for reading and writing configuration files.""" +__all__ = ["GitConfigParser", "SectionConstraint"] + import abc import configparser as cp import fnmatch @@ -40,9 +42,10 @@ from git.types import Lit_config_levels, ConfigLevels_Tup, PathLike, assert_never, _T if TYPE_CHECKING: - from git.repo.base import Repo from io import BytesIO + from git.repo.base import Repo + T_ConfigParser = TypeVar("T_ConfigParser", bound="GitConfigParser") T_OMD_value = TypeVar("T_OMD_value", str, bytes, int, float, bool) @@ -58,8 +61,6 @@ # ------------------------------------------------------------- -__all__ = ("GitConfigParser", "SectionConstraint") - _logger = logging.getLogger(__name__) CONFIG_LEVELS: ConfigLevels_Tup = ("system", "user", "global", "repository") diff --git a/git/db.py b/git/db.py index 5b2ca4de2..cacd030d0 100644 --- a/git/db.py +++ b/git/db.py @@ -3,27 +3,26 @@ """Module with our own gitdb implementation - it uses the git command.""" -from git.util import bin_to_hex, hex_to_bin -from gitdb.base import OInfo, OStream -from gitdb.db import GitDB -from gitdb.db import LooseObjectDB +__all__ = ["GitCmdObjectDB", "GitDB"] +from gitdb.base import OInfo, OStream +from gitdb.db import GitDB, LooseObjectDB from gitdb.exc import BadObject + +from git.util import bin_to_hex, hex_to_bin from git.exc import GitCommandError # typing------------------------------------------------- from typing import TYPE_CHECKING + from git.types import PathLike if TYPE_CHECKING: from git.cmd import Git - # -------------------------------------------------------- -__all__ = ("GitCmdObjectDB", "GitDB") - class GitCmdObjectDB(LooseObjectDB): """A database representing the default git object store, which includes loose diff --git a/git/diff.py b/git/diff.py index a6322ff57..0e39fe7a8 100644 --- a/git/diff.py +++ b/git/diff.py @@ -3,17 +3,17 @@ # This module is part of GitPython and is released under the # 3-Clause BSD License: https://opensource.org/license/bsd-3-clause/ +__all__ = ["DiffConstants", "NULL_TREE", "INDEX", "Diffable", "DiffIndex", "Diff"] + import enum import re from git.cmd import handle_process_output from git.compat import defenc +from git.objects.blob import Blob +from git.objects.util import mode_str_to_int from git.util import finalize_process, hex_to_bin -from .objects.blob import Blob -from .objects.util import mode_str_to_int - - # typing ------------------------------------------------------------------ from typing import ( @@ -23,34 +23,27 @@ Match, Optional, Tuple, + TYPE_CHECKING, TypeVar, Union, - TYPE_CHECKING, cast, ) from git.types import Literal, PathLike if TYPE_CHECKING: - from .objects.tree import Tree - from .objects import Commit - from git.repo.base import Repo - from git.objects.base import IndexObject from subprocess import Popen - from git import Git - -Lit_change_type = Literal["A", "D", "C", "M", "R", "T", "U"] + from git.cmd import Git + from git.objects.base import IndexObject + from git.objects.commit import Commit + from git.objects.tree import Tree + from git.repo.base import Repo -# def is_change_type(inp: str) -> TypeGuard[Lit_change_type]: -# # return True -# return inp in ['A', 'D', 'C', 'M', 'R', 'T', 'U'] +Lit_change_type = Literal["A", "D", "C", "M", "R", "T", "U"] # ------------------------------------------------------------------------ -__all__ = ("DiffConstants", "NULL_TREE", "INDEX", "Diffable", "DiffIndex", "Diff") - - @enum.unique class DiffConstants(enum.Enum): """Special objects for :meth:`Diffable.diff`. @@ -693,7 +686,6 @@ def _handle_diff_line(lines_bytes: bytes, repo: "Repo", index: DiffIndex) -> Non # Change type can be R100 # R: status letter # 100: score (in case of copy and rename) - # assert is_change_type(_change_type[0]), f"Unexpected value for change_type received: {_change_type[0]}" change_type: Lit_change_type = cast(Lit_change_type, _change_type[0]) score_str = "".join(_change_type[1:]) score = int(score_str) if score_str.isdigit() else None diff --git a/git/exc.py b/git/exc.py index 9f6462b39..583eee8c1 100644 --- a/git/exc.py +++ b/git/exc.py @@ -42,12 +42,14 @@ ParseError, UnsupportedOperation, ) + from git.compat import safe_decode from git.util import remove_password_if_present # typing ---------------------------------------------------- -from typing import List, Sequence, Tuple, Union, TYPE_CHECKING +from typing import List, Sequence, Tuple, TYPE_CHECKING, Union + from git.types import PathLike if TYPE_CHECKING: diff --git a/git/index/__init__.py b/git/index/__init__.py index c65722cd8..ba48110fd 100644 --- a/git/index/__init__.py +++ b/git/index/__init__.py @@ -3,5 +3,14 @@ """Initialize the index package.""" -from .base import * # noqa: F401 F403 -from .typ import * # noqa: F401 F403 +__all__ = [ + "BaseIndexEntry", + "BlobFilter", + "CheckoutError", + "IndexEntry", + "IndexFile", + "StageType", +] + +from .base import CheckoutError, IndexFile +from .typ import BaseIndexEntry, BlobFilter, IndexEntry, StageType diff --git a/git/index/base.py b/git/index/base.py index fb91e092c..b8161ea52 100644 --- a/git/index/base.py +++ b/git/index/base.py @@ -6,6 +6,8 @@ """Module containing :class:`IndexFile`, an Index implementation facilitating all kinds of index manipulations such as querying and merging.""" +__all__ = ["IndexFile", "CheckoutError", "StageType"] + import contextlib import datetime import glob @@ -17,6 +19,9 @@ import sys import tempfile +from gitdb.base import IStream +from gitdb.db import MemoryDB + from git.compat import defenc, force_bytes import git.diff as git_diff from git.exc import CheckoutError, GitCommandError, GitError, InvalidGitRepositoryError @@ -31,8 +36,6 @@ unbare_repo, to_bin_sha, ) -from gitdb.base import IStream -from gitdb.db import MemoryDB from .fun import ( S_IFGITLINK, @@ -81,9 +84,6 @@ # ------------------------------------------------------------------------------------ -__all__ = ("IndexFile", "CheckoutError", "StageType") - - @contextlib.contextmanager def _named_temporary_file_for_subprocess(directory: PathLike) -> Generator[str, None, None]: """Create a named temporary file git subprocesses can open, deleting it afterward. diff --git a/git/index/fun.py b/git/index/fun.py index 001e8f6f2..59cce6ae6 100644 --- a/git/index/fun.py +++ b/git/index/fun.py @@ -4,22 +4,28 @@ """Standalone functions to accompany the index implementation and make it more versatile.""" +__all__ = [ + "write_cache", + "read_cache", + "write_tree_from_cache", + "entry_key", + "stat_mode_to_index_mode", + "S_IFGITLINK", + "run_commit_hook", + "hook_path", +] + from io import BytesIO import os import os.path as osp from pathlib import Path -from stat import ( - S_IFDIR, - S_IFLNK, - S_ISLNK, - S_ISDIR, - S_IFMT, - S_IFREG, - S_IXUSR, -) +from stat import S_IFDIR, S_IFLNK, S_IFMT, S_IFREG, S_ISDIR, S_ISLNK, S_IXUSR import subprocess import sys +from gitdb.base import IStream +from gitdb.typ import str_tree_type + from git.cmd import handle_process_output, safer_popen from git.compat import defenc, force_bytes, force_text, safe_decode from git.exc import HookExecutionError, UnmergedEntriesError @@ -29,8 +35,6 @@ tree_to_stream, ) from git.util import IndexFileSHA1Writer, finalize_process -from gitdb.base import IStream -from gitdb.typ import str_tree_type from .typ import BaseIndexEntry, IndexEntry, CE_NAMEMASK, CE_STAGESHIFT from .util import pack, unpack @@ -42,31 +46,18 @@ from git.types import PathLike if TYPE_CHECKING: - from .base import IndexFile from git.db import GitCmdObjectDB from git.objects.tree import TreeCacheTup - # from git.objects.fun import EntryTupOrNone + from .base import IndexFile # ------------------------------------------------------------------------------------ - S_IFGITLINK = S_IFLNK | S_IFDIR """Flags for a submodule.""" CE_NAMEMASK_INV = ~CE_NAMEMASK -__all__ = ( - "write_cache", - "read_cache", - "write_tree_from_cache", - "entry_key", - "stat_mode_to_index_mode", - "S_IFGITLINK", - "run_commit_hook", - "hook_path", -) - def hook_path(name: str, git_dir: PathLike) -> str: """:return: path to the given named hook in the given git repository directory""" diff --git a/git/index/typ.py b/git/index/typ.py index ffd76dc46..974252528 100644 --- a/git/index/typ.py +++ b/git/index/typ.py @@ -3,12 +3,14 @@ """Additional types used by the index.""" +__all__ = ["BlobFilter", "BaseIndexEntry", "IndexEntry", "StageType"] + from binascii import b2a_hex from pathlib import Path -from .util import pack, unpack from git.objects import Blob +from .util import pack, unpack # typing ---------------------------------------------------------------------- @@ -23,8 +25,6 @@ # --------------------------------------------------------------------------------- -__all__ = ("BlobFilter", "BaseIndexEntry", "IndexEntry", "StageType") - # { Invariants CE_NAMEMASK = 0x0FFF CE_STAGEMASK = 0x3000 diff --git a/git/index/util.py b/git/index/util.py index 0bad11571..e59cb609f 100644 --- a/git/index/util.py +++ b/git/index/util.py @@ -3,6 +3,8 @@ """Index utilities.""" +__all__ = ["TemporaryFileSwap", "post_clear_cache", "default_index", "git_working_dir"] + import contextlib from functools import wraps import os @@ -22,14 +24,9 @@ # --------------------------------------------------------------------------------- - -__all__ = ("TemporaryFileSwap", "post_clear_cache", "default_index", "git_working_dir") - # { Aliases pack = struct.pack unpack = struct.unpack - - # } END aliases diff --git a/git/objects/__init__.py b/git/objects/__init__.py index 1061ec874..4447ca50d 100644 --- a/git/objects/__init__.py +++ b/git/objects/__init__.py @@ -3,22 +3,23 @@ """Import all submodules' main classes into the package space.""" -import inspect +__all__ = [ + "IndexObject", + "Object", + "Blob", + "Commit", + "Submodule", + "UpdateProgress", + "RootModule", + "RootUpdateProgress", + "TagObject", + "Tree", + "TreeModifier", +] -from .base import * # noqa: F403 -from .blob import * # noqa: F403 -from .commit import * # noqa: F403 -from .submodule import util as smutil -from .submodule.base import * # noqa: F403 -from .submodule.root import * # noqa: F403 -from .tag import * # noqa: F403 -from .tree import * # noqa: F403 - -# Fix import dependency - add IndexObject to the util module, so that it can be imported -# by the submodule.base. -smutil.IndexObject = IndexObject # type: ignore[attr-defined] # noqa: F405 -smutil.Object = Object # type: ignore[attr-defined] # noqa: F405 -del smutil - -# Must come after submodule was made available. -__all__ = [name for name, obj in locals().items() if not (name.startswith("_") or inspect.ismodule(obj))] +from .base import IndexObject, Object +from .blob import Blob +from .commit import Commit +from .submodule import RootModule, RootUpdateProgress, Submodule, UpdateProgress +from .tag import TagObject +from .tree import Tree, TreeModifier diff --git a/git/objects/base.py b/git/objects/base.py index 22d939aa6..eeaebc09b 100644 --- a/git/objects/base.py +++ b/git/objects/base.py @@ -3,15 +3,17 @@ # This module is part of GitPython and is released under the # 3-Clause BSD License: https://opensource.org/license/bsd-3-clause/ -import gitdb.typ as dbtyp +__all__ = ["Object", "IndexObject"] + import os.path as osp +import gitdb.typ as dbtyp + from git.exc import WorkTreeRepositoryUnsupported -from git.util import LazyMixin, join_path_native, stream_copy, bin_to_hex +from git.util import LazyMixin, bin_to_hex, join_path_native, stream_copy from .util import get_object_type_by_name - # typing ------------------------------------------------------------------ from typing import Any, TYPE_CHECKING, Union @@ -24,16 +26,14 @@ from git.refs.reference import Reference from git.repo import Repo - from .tree import Tree from .blob import Blob from .submodule.base import Submodule + from .tree import Tree IndexObjUnion = Union["Tree", "Blob", "Submodule"] # -------------------------------------------------------------------------- -__all__ = ("Object", "IndexObject") - class Object(LazyMixin): """Base class for classes representing git object types. diff --git a/git/objects/blob.py b/git/objects/blob.py index 122d5f731..58de59642 100644 --- a/git/objects/blob.py +++ b/git/objects/blob.py @@ -3,17 +3,17 @@ # This module is part of GitPython and is released under the # 3-Clause BSD License: https://opensource.org/license/bsd-3-clause/ +__all__ = ["Blob"] + from mimetypes import guess_type import sys -from . import base - if sys.version_info >= (3, 8): from typing import Literal else: from typing_extensions import Literal -__all__ = ("Blob",) +from . import base class Blob(base.IndexObject): diff --git a/git/objects/commit.py b/git/objects/commit.py index 6a60c30bd..8de52980c 100644 --- a/git/objects/commit.py +++ b/git/objects/commit.py @@ -3,6 +3,8 @@ # This module is part of GitPython and is released under the # 3-Clause BSD License: https://opensource.org/license/bsd-3-clause/ +__all__ = ["Commit"] + from collections import defaultdict import datetime from io import BytesIO @@ -14,10 +16,12 @@ from time import altzone, daylight, localtime, time, timezone from gitdb import IStream + from git.cmd import Git from git.diff import Diffable -from git.util import hex_to_bin, Actor, Stats, finalize_process +from git.util import Actor, Stats, finalize_process, hex_to_bin +from . import base from .tree import Tree from .util import ( Serializable, @@ -27,7 +31,6 @@ parse_actor_and_date, parse_date, ) -from . import base # typing ------------------------------------------------------------------ @@ -59,8 +62,6 @@ _logger = logging.getLogger(__name__) -__all__ = ("Commit",) - class Commit(base.Object, TraversableIterableObj, Diffable, Serializable): """Wraps a git commit object. diff --git a/git/objects/fun.py b/git/objects/fun.py index 5bd8a3d62..fe57da13a 100644 --- a/git/objects/fun.py +++ b/git/objects/fun.py @@ -3,8 +3,14 @@ """Functions that are supposed to be as fast as possible.""" -from stat import S_ISDIR +__all__ = [ + "tree_to_stream", + "tree_entries_from_data", + "traverse_trees_recursive", + "traverse_tree_recursive", +] +from stat import S_ISDIR from git.compat import safe_decode, defenc @@ -23,22 +29,15 @@ if TYPE_CHECKING: from _typeshed import ReadableBuffer + from git import GitCmdObjectDB -EntryTup = Tuple[bytes, int, str] # same as TreeCacheTup in tree.py +EntryTup = Tuple[bytes, int, str] # Same as TreeCacheTup in tree.py. EntryTupOrNone = Union[EntryTup, None] # --------------------------------------------------- -__all__ = ( - "tree_to_stream", - "tree_entries_from_data", - "traverse_trees_recursive", - "traverse_tree_recursive", -) - - def tree_to_stream(entries: Sequence[EntryTup], write: Callable[["ReadableBuffer"], Union[int, None]]) -> None: """Write the given list of entries into a stream using its ``write`` method. diff --git a/git/objects/submodule/__init__.py b/git/objects/submodule/__init__.py index b11b568f2..c0604e76f 100644 --- a/git/objects/submodule/__init__.py +++ b/git/objects/submodule/__init__.py @@ -1,5 +1,7 @@ # This module is part of GitPython and is released under the # 3-Clause BSD License: https://opensource.org/license/bsd-3-clause/ -# NOTE: Cannot import anything here as the top-level __init__ has to handle -# our dependencies. +__all__ = ["Submodule", "UpdateProgress", "RootModule", "RootUpdateProgress"] + +from .base import Submodule, UpdateProgress +from .root import RootModule, RootUpdateProgress diff --git a/git/objects/submodule/base.py b/git/objects/submodule/base.py index d01aa448f..fa60bcdaf 100644 --- a/git/objects/submodule/base.py +++ b/git/objects/submodule/base.py @@ -1,6 +1,8 @@ # This module is part of GitPython and is released under the # 3-Clause BSD License: https://opensource.org/license/bsd-3-clause/ +__all__ = ["Submodule", "UpdateProgress"] + import gc from io import BytesIO import logging @@ -68,8 +70,6 @@ # ----------------------------------------------------------------------------- -__all__ = ["Submodule", "UpdateProgress"] - _logger = logging.getLogger(__name__) diff --git a/git/objects/submodule/root.py b/git/objects/submodule/root.py index ae56e5ef4..d93193fa3 100644 --- a/git/objects/submodule/root.py +++ b/git/objects/submodule/root.py @@ -1,10 +1,13 @@ # This module is part of GitPython and is released under the # 3-Clause BSD License: https://opensource.org/license/bsd-3-clause/ +__all__ = ["RootModule", "RootUpdateProgress"] + import logging import git from git.exc import InvalidGitRepositoryError + from .base import Submodule, UpdateProgress from .util import find_first_remote_branch @@ -20,8 +23,6 @@ # ---------------------------------------------------------------------------- -__all__ = ["RootModule", "RootUpdateProgress"] - _logger = logging.getLogger(__name__) diff --git a/git/objects/submodule/util.py b/git/objects/submodule/util.py index 10b994e9b..c021510d8 100644 --- a/git/objects/submodule/util.py +++ b/git/objects/submodule/util.py @@ -1,12 +1,20 @@ # This module is part of GitPython and is released under the # 3-Clause BSD License: https://opensource.org/license/bsd-3-clause/ -import git -from git.exc import InvalidGitRepositoryError -from git.config import GitConfigParser +__all__ = [ + "sm_section", + "sm_name", + "mkhead", + "find_first_remote_branch", + "SubmoduleConfigParser", +] + from io import BytesIO import weakref +import git +from git.config import GitConfigParser +from git.exc import InvalidGitRepositoryError # typing ----------------------------------------------------------------------- @@ -15,21 +23,13 @@ from git.types import PathLike if TYPE_CHECKING: - from .base import Submodule from weakref import ReferenceType - from git.repo import Repo - from git.refs import Head - from git import Remote - from git.refs import RemoteReference + from git.refs import Head, RemoteReference + from git.remote import Remote + from git.repo import Repo -__all__ = ( - "sm_section", - "sm_name", - "mkhead", - "find_first_remote_branch", - "SubmoduleConfigParser", -) + from .base import Submodule # { Utilities @@ -65,7 +65,6 @@ def find_first_remote_branch(remotes: Sequence["Remote"], branch_name: str) -> " # } END utilities - # { Classes diff --git a/git/objects/tag.py b/git/objects/tag.py index 52d79751f..a3bb0b882 100644 --- a/git/objects/tag.py +++ b/git/objects/tag.py @@ -9,12 +9,17 @@ For lightweight tags, see the :mod:`git.refs.tag` module. """ +__all__ = ["TagObject"] + import sys +from git.compat import defenc +from git.util import hex_to_bin + from . import base from .util import get_object_type_by_name, parse_actor_and_date -from ..util import hex_to_bin -from ..compat import defenc + +# typing ---------------------------------------------- from typing import List, TYPE_CHECKING, Union @@ -26,11 +31,12 @@ if TYPE_CHECKING: from git.repo import Repo from git.util import Actor - from .commit import Commit + from .blob import Blob + from .commit import Commit from .tree import Tree -__all__ = ("TagObject",) +# --------------------------------------------------- class TagObject(base.Object): diff --git a/git/objects/tree.py b/git/objects/tree.py index c74df58a9..09184a781 100644 --- a/git/objects/tree.py +++ b/git/objects/tree.py @@ -3,16 +3,18 @@ # This module is part of GitPython and is released under the # 3-Clause BSD License: https://opensource.org/license/bsd-3-clause/ +__all__ = ["TreeModifier", "Tree"] + import sys import git.diff as git_diff from git.util import IterableList, join_path, to_bin_sha +from . import util from .base import IndexObjUnion, IndexObject from .blob import Blob from .fun import tree_entries_from_data, tree_to_stream from .submodule.base import Submodule -from . import util # typing ------------------------------------------------- @@ -39,23 +41,17 @@ if TYPE_CHECKING: from io import BytesIO + from git.repo import Repo TreeCacheTup = Tuple[bytes, int, str] TraversedTreeTup = Union[Tuple[Union["Tree", None], IndexObjUnion, Tuple["Submodule", "Submodule"]]] - -# def is_tree_cache(inp: Tuple[bytes, int, str]) -> TypeGuard[TreeCacheTup]: -# return isinstance(inp[0], bytes) and isinstance(inp[1], int) and isinstance([inp], str) - # -------------------------------------------------------- - cmp: Callable[[str, str], int] = lambda a, b: (a > b) - (a < b) -__all__ = ("TreeModifier", "Tree") - class TreeModifier: """A utility class providing methods to alter the underlying cache in a list-like @@ -125,7 +121,6 @@ def add(self, sha: bytes, mode: int, name: str, force: bool = False) -> "TreeMod index = self._index_by_name(name) item = (sha, mode, name) - # assert is_tree_cache(item) if index == -1: self._cache.append(item) diff --git a/git/objects/util.py b/git/objects/util.py index 297b33b70..5c56e6134 100644 --- a/git/objects/util.py +++ b/git/objects/util.py @@ -3,28 +3,41 @@ # This module is part of GitPython and is released under the # 3-Clause BSD License: https://opensource.org/license/bsd-3-clause/ -"""General utility functions.""" +"""Utility functions for working with git objects.""" + +__all__ = [ + "get_object_type_by_name", + "parse_date", + "parse_actor_and_date", + "ProcessStreamAdapter", + "Traversable", + "altz_to_utctz_str", + "utctz_to_altz", + "verify_utctz", + "Actor", + "tzoffset", + "utc", +] from abc import ABC, abstractmethod import calendar from collections import deque from datetime import datetime, timedelta, tzinfo -from string import digits import re +from string import digits import time import warnings -from git.util import IterableList, IterableObj, Actor +from git.util import Actor, IterableList, IterableObj # typing ------------------------------------------------------------ + from typing import ( Any, Callable, Deque, Iterator, - # Generic, NamedTuple, - overload, Sequence, TYPE_CHECKING, Tuple, @@ -32,21 +45,23 @@ TypeVar, Union, cast, + overload, ) -from git.types import Has_id_attribute, Literal # , _T +from git.types import Has_id_attribute, Literal if TYPE_CHECKING: from io import BytesIO, StringIO - from .commit import Commit - from .blob import Blob - from .tag import TagObject - from .tree import Tree, TraversedTreeTup from subprocess import Popen - from .submodule.base import Submodule + from git.types import Protocol, runtime_checkable + + from .blob import Blob + from .commit import Commit + from .submodule.base import Submodule + from .tag import TagObject + from .tree import TraversedTreeTup, Tree else: - # Protocol = Generic[_T] # Needed for typing bug #572? Protocol = ABC def runtime_checkable(f): @@ -68,20 +83,6 @@ class TraverseNT(NamedTuple): # -------------------------------------------------------------------- -__all__ = ( - "get_object_type_by_name", - "parse_date", - "parse_actor_and_date", - "ProcessStreamAdapter", - "Traversable", - "altz_to_utctz_str", - "utctz_to_altz", - "verify_utctz", - "Actor", - "tzoffset", - "utc", -) - ZERO = timedelta(0) # { Functions diff --git a/git/refs/__init__.py b/git/refs/__init__.py index b0233e902..d6157e6f3 100644 --- a/git/refs/__init__.py +++ b/git/refs/__init__.py @@ -1,12 +1,21 @@ # This module is part of GitPython and is released under the # 3-Clause BSD License: https://opensource.org/license/bsd-3-clause/ -# Import all modules in order, fix the names they require. +__all__ = [ + "HEAD", + "Head", + "RefLog", + "RefLogEntry", + "Reference", + "RemoteReference", + "SymbolicReference", + "Tag", + "TagReference", +] -from .symbolic import * # noqa: F401 F403 -from .reference import * # noqa: F401 F403 -from .head import * # noqa: F401 F403 -from .tag import * # noqa: F401 F403 -from .remote import * # noqa: F401 F403 - -from .log import * # noqa: F401 F403 +from .head import HEAD, Head +from .log import RefLog, RefLogEntry +from .reference import Reference +from .remote import RemoteReference +from .symbolic import SymbolicReference +from .tag import Tag, TagReference diff --git a/git/refs/head.py b/git/refs/head.py index 86321d9ea..7e6fc3377 100644 --- a/git/refs/head.py +++ b/git/refs/head.py @@ -6,12 +6,14 @@ Note the distinction between the :class:`HEAD` and :class:`Head` classes. """ +__all__ = ["HEAD", "Head"] + from git.config import GitConfigParser, SectionConstraint -from git.util import join_path from git.exc import GitCommandError +from git.util import join_path -from .symbolic import SymbolicReference from .reference import Reference +from .symbolic import SymbolicReference # typing --------------------------------------------------- @@ -26,8 +28,6 @@ # ------------------------------------------------------------------- -__all__ = ["HEAD", "Head"] - def strip_quotes(string: str) -> str: if string.startswith('"') and string.endswith('"'): @@ -36,8 +36,8 @@ def strip_quotes(string: str) -> str: class HEAD(SymbolicReference): - """Special case of a SymbolicReference representing the repository's HEAD - reference.""" + """Special case of a :class:`~git.refs.symbolic.SymbolicReference` representing the + repository's HEAD reference.""" _HEAD_NAME = "HEAD" _ORIG_HEAD_NAME = "ORIG_HEAD" diff --git a/git/refs/log.py b/git/refs/log.py index f98f56f11..17e3a94b3 100644 --- a/git/refs/log.py +++ b/git/refs/log.py @@ -1,44 +1,43 @@ # This module is part of GitPython and is released under the # 3-Clause BSD License: https://opensource.org/license/bsd-3-clause/ +__all__ = ["RefLog", "RefLogEntry"] + from mmap import mmap +import os.path as osp import re import time as _time from git.compat import defenc from git.objects.util import ( - parse_date, Serializable, altz_to_utctz_str, + parse_date, ) from git.util import ( Actor, LockedFD, LockFile, assure_directory_exists, - to_native_path, bin_to_hex, file_contents_ro_filepath, + to_native_path, ) -import os.path as osp - - # typing ------------------------------------------------------------------ -from typing import Iterator, List, Tuple, Union, TYPE_CHECKING +from typing import Iterator, List, Tuple, TYPE_CHECKING, Union from git.types import PathLike if TYPE_CHECKING: from io import BytesIO - from git.refs import SymbolicReference + from git.config import GitConfigParser, SectionConstraint + from git.refs import SymbolicReference # ------------------------------------------------------------------------------ -__all__ = ["RefLog", "RefLogEntry"] - class RefLogEntry(Tuple[str, str, Actor, Tuple[int, int], str]): """Named tuple allowing easy access to the revlog data fields.""" diff --git a/git/refs/reference.py b/git/refs/reference.py index 62fb58420..e5d473779 100644 --- a/git/refs/reference.py +++ b/git/refs/reference.py @@ -1,7 +1,10 @@ # This module is part of GitPython and is released under the # 3-Clause BSD License: https://opensource.org/license/bsd-3-clause/ +__all__ = ["Reference"] + from git.util import IterableObj, LazyMixin + from .symbolic import SymbolicReference, T_References # typing ------------------------------------------------------------------ @@ -15,8 +18,6 @@ # ------------------------------------------------------------------------------ -__all__ = ["Reference"] - # { Utilities @@ -34,7 +35,7 @@ def wrapper(self: T_References, *args: Any) -> _T: return wrapper -# }END utilities +# } END utilities class Reference(SymbolicReference, LazyMixin, IterableObj): @@ -142,7 +143,7 @@ def iter_items( but will return non-detached references as well.""" return cls._iter_items(repo, common_path) - # }END interface + # } END interface # { Remote Interface diff --git a/git/refs/remote.py b/git/refs/remote.py index 3f9c6c6be..b4f4f7b36 100644 --- a/git/refs/remote.py +++ b/git/refs/remote.py @@ -3,24 +3,23 @@ """Module implementing a remote object allowing easy access to git remotes.""" +__all__ = ["RemoteReference"] + import os from git.util import join_path from .head import Head - -__all__ = ["RemoteReference"] - # typing ------------------------------------------------------------------ -from typing import Any, Iterator, NoReturn, Union, TYPE_CHECKING -from git.types import PathLike +from typing import Any, Iterator, NoReturn, TYPE_CHECKING, Union +from git.types import PathLike if TYPE_CHECKING: + from git.remote import Remote from git.repo import Repo - from git import Remote # ------------------------------------------------------------------------------ diff --git a/git/refs/symbolic.py b/git/refs/symbolic.py index 2701f9f2b..510850b2e 100644 --- a/git/refs/symbolic.py +++ b/git/refs/symbolic.py @@ -1,10 +1,14 @@ # This module is part of GitPython and is released under the # 3-Clause BSD License: https://opensource.org/license/bsd-3-clause/ +__all__ = ["SymbolicReference"] + import os +from gitdb.exc import BadName, BadObject + from git.compat import defenc -from git.objects import Object +from git.objects.base import Object from git.objects.commit import Commit from git.refs.log import RefLog from git.util import ( @@ -15,7 +19,6 @@ join_path_native, to_native_path_linux, ) -from gitdb.exc import BadName, BadObject # typing ------------------------------------------------------------------ @@ -30,6 +33,7 @@ Union, cast, ) + from git.types import AnyGitObject, PathLike if TYPE_CHECKING: @@ -45,9 +49,6 @@ # ------------------------------------------------------------------------------ -__all__ = ["SymbolicReference"] - - def _git_dir(repo: "Repo", path: Union[PathLike, None]) -> PathLike: """Find the git dir that is appropriate for the path.""" name = f"{path}" diff --git a/git/refs/tag.py b/git/refs/tag.py index f653d4e7d..1e38663ae 100644 --- a/git/refs/tag.py +++ b/git/refs/tag.py @@ -8,10 +8,10 @@ :mod:`git.objects.tag` module. """ -from .reference import Reference - __all__ = ["TagReference", "Tag"] +from .reference import Reference + # typing ------------------------------------------------------------------ from typing import Any, TYPE_CHECKING, Type, Union @@ -19,12 +19,10 @@ from git.types import AnyGitObject, PathLike if TYPE_CHECKING: - from git.objects import Commit - from git.objects import TagObject + from git.objects import Commit, TagObject from git.refs import SymbolicReference from git.repo import Repo - # ------------------------------------------------------------------------------ diff --git a/git/remote.py b/git/remote.py index 2c452022e..f2ecd0f36 100644 --- a/git/remote.py +++ b/git/remote.py @@ -5,6 +5,8 @@ """Module implementing a remote object allowing easy access to git remotes.""" +__all__ = ["RemoteProgress", "PushInfo", "FetchInfo", "Remote"] + import contextlib import logging import re @@ -50,16 +52,10 @@ flagKeyLiteral = Literal[" ", "!", "+", "-", "*", "=", "t", "?"] -# def is_flagKeyLiteral(inp: str) -> TypeGuard[flagKeyLiteral]: -# return inp in [' ', '!', '+', '-', '=', '*', 't', '?'] - - # ------------------------------------------------------------- _logger = logging.getLogger(__name__) -__all__ = ("RemoteProgress", "PushInfo", "FetchInfo", "Remote") - # { Utilities @@ -415,7 +411,6 @@ def _from_line(cls, repo: "Repo", line: str, fetch_line: str) -> "FetchInfo": remote_local_ref_str, note, ) = match.groups() - # assert is_flagKeyLiteral(control_character), f"{control_character}" control_character = cast(flagKeyLiteral, control_character) try: _new_hex_sha, _fetch_operation, fetch_note = fetch_line.split("\t") diff --git a/git/repo/__init__.py b/git/repo/__init__.py index 50a8c6f86..66319ef95 100644 --- a/git/repo/__init__.py +++ b/git/repo/__init__.py @@ -3,4 +3,6 @@ """Initialize the repo package.""" -from .base import Repo as Repo # noqa: F401 +__all__ = ["Repo"] + +from .base import Repo diff --git a/git/repo/base.py b/git/repo/base.py index ce164274e..51ea76901 100644 --- a/git/repo/base.py +++ b/git/repo/base.py @@ -5,6 +5,8 @@ from __future__ import annotations +__all__ = ["Repo"] + import gc import logging import os @@ -92,8 +94,6 @@ _logger = logging.getLogger(__name__) -__all__ = ("Repo",) - class BlameEntry(NamedTuple): commit: Dict[str, Commit] diff --git a/git/repo/fun.py b/git/repo/fun.py index 738e5816d..e44d9c644 100644 --- a/git/repo/fun.py +++ b/git/repo/fun.py @@ -5,18 +5,31 @@ from __future__ import annotations +__all__ = [ + "rev_parse", + "is_git_dir", + "touch", + "find_submodule_git_dir", + "name_to_object", + "short_to_long", + "deref_tag", + "to_commit", + "find_worktree_git_dir", +] + import os import os.path as osp from pathlib import Path import stat from string import digits +from gitdb.exc import BadName, BadObject + from git.cmd import Git from git.exc import WorkTreeRepositoryUnsupported from git.objects import Object from git.refs import SymbolicReference -from git.util import hex_to_bin, bin_to_hex, cygpath -from gitdb.exc import BadName, BadObject +from git.util import cygpath, bin_to_hex, hex_to_bin # Typing ---------------------------------------------------------------------- @@ -29,22 +42,11 @@ from git.objects import Commit, TagObject from git.refs.reference import Reference from git.refs.tag import Tag + from .base import Repo # ---------------------------------------------------------------------------- -__all__ = ( - "rev_parse", - "is_git_dir", - "touch", - "find_submodule_git_dir", - "name_to_object", - "short_to_long", - "deref_tag", - "to_commit", - "find_worktree_git_dir", -) - def touch(filename: str) -> str: with open(filename, "ab"): diff --git a/git/types.py b/git/types.py index e3ae9e3d5..230422dff 100644 --- a/git/types.py +++ b/git/types.py @@ -3,7 +3,7 @@ import os import sys -from typing import ( # noqa: F401 +from typing import ( Any, Callable, Dict, @@ -17,7 +17,7 @@ ) if sys.version_info >= (3, 8): - from typing import ( # noqa: F401 + from typing import ( Literal, Protocol, SupportsIndex as SupportsIndex, @@ -25,7 +25,7 @@ runtime_checkable, ) else: - from typing_extensions import ( # noqa: F401 + from typing_extensions import ( Literal, Protocol, SupportsIndex as SupportsIndex, diff --git a/git/util.py b/git/util.py index 37986edaa..5839f9720 100644 --- a/git/util.py +++ b/git/util.py @@ -3,6 +3,32 @@ # This module is part of GitPython and is released under the # 3-Clause BSD License: https://opensource.org/license/bsd-3-clause/ +import sys + +__all__ = [ + "stream_copy", + "join_path", + "to_native_path_linux", + "join_path_native", + "Stats", + "IndexFileSHA1Writer", + "IterableObj", + "IterableList", + "BlockingLockFile", + "LockFile", + "Actor", + "get_user_id", + "assure_directory_exists", + "RemoteProgress", + "CallableRemoteProgress", + "rmtree", + "unbare_repo", + "HIDE_WINDOWS_KNOWN_ERRORS", +] + +if sys.platform == "win32": + __all__.append("to_native_path_windows") + from abc import abstractmethod import contextlib from functools import wraps @@ -16,11 +42,27 @@ import shutil import stat import subprocess -import sys import time from urllib.parse import urlsplit, urlunsplit import warnings +# NOTE: Unused imports can be improved now that CI testing has fully resumed. Some of +# these be used indirectly through other GitPython modules, which avoids having to write +# gitdb all the time in their imports. They are not in __all__, at least currently, +# because they could be removed or changed at any time, and so should not be considered +# conceptually public to code outside GitPython. Linters of course do not like it. +from gitdb.util import ( + LazyMixin, # noqa: F401 + LockedFD, # noqa: F401 + bin_to_hex, # noqa: F401 + file_contents_ro, # noqa: F401 + file_contents_ro_filepath, # noqa: F401 + hex_to_bin, # noqa: F401 + make_sha, + to_bin_sha, # noqa: F401 + to_hex_sha, # noqa: F401 +) + # typing --------------------------------------------------------- from typing import ( @@ -37,73 +79,36 @@ Pattern, Sequence, Tuple, + TYPE_CHECKING, TypeVar, Union, - TYPE_CHECKING, cast, overload, ) if TYPE_CHECKING: + from git.cmd import Git + from git.config import GitConfigParser, SectionConstraint from git.remote import Remote from git.repo.base import Repo - from git.config import GitConfigParser, SectionConstraint - from git import Git -from .types import ( +from git.types import ( + Files_TD, + Has_id_attribute, + HSH_TD, Literal, - SupportsIndex, - Protocol, - runtime_checkable, # because behind py version guards PathLike, - HSH_TD, + Protocol, + SupportsIndex, Total_TD, - Files_TD, # aliases - Has_id_attribute, + runtime_checkable, ) # --------------------------------------------------------------------- -from gitdb.util import ( # noqa: F401 # @IgnorePep8 - make_sha, - LockedFD, # @UnusedImport - file_contents_ro, # @UnusedImport - file_contents_ro_filepath, # @UnusedImport - LazyMixin, # @UnusedImport - to_hex_sha, # @UnusedImport - to_bin_sha, # @UnusedImport - bin_to_hex, # @UnusedImport - hex_to_bin, # @UnusedImport -) - T_IterableObj = TypeVar("T_IterableObj", bound=Union["IterableObj", "Has_id_attribute"], covariant=True) # So IterableList[Head] is subtype of IterableList[IterableObj]. -# NOTE: Some of the unused imports might be used/imported by others. -# Handle once test-cases are back up and running. -# Most of these are unused here, but are for use by git-python modules so these -# don't see gitdb all the time. Flake of course doesn't like it. -__all__ = [ - "stream_copy", - "join_path", - "to_native_path_linux", - "join_path_native", - "Stats", - "IndexFileSHA1Writer", - "IterableObj", - "IterableList", - "BlockingLockFile", - "LockFile", - "Actor", - "get_user_id", - "assure_directory_exists", - "RemoteProgress", - "CallableRemoteProgress", - "rmtree", - "unbare_repo", - "HIDE_WINDOWS_KNOWN_ERRORS", -] - _logger = logging.getLogger(__name__) @@ -292,7 +297,6 @@ def to_native_path_linux(path: PathLike) -> str: path = str(path) return path.replace("\\", "/") - __all__.append("to_native_path_windows") to_native_path = to_native_path_windows else: # No need for any work on Linux. diff --git a/setup.py b/setup.py index 143206653..f28fedb85 100755 --- a/setup.py +++ b/setup.py @@ -1,8 +1,8 @@ #!/usr/bin/env python import os -import sys from pathlib import Path +import sys from typing import Sequence from setuptools import setup, find_packages diff --git a/test/lib/helper.py b/test/lib/helper.py index 45a778b7d..5d91447ea 100644 --- a/test/lib/helper.py +++ b/test/lib/helper.py @@ -3,6 +3,22 @@ # This module is part of GitPython and is released under the # 3-Clause BSD License: https://opensource.org/license/bsd-3-clause/ +__all__ = [ + "fixture_path", + "fixture", + "StringProcessAdapter", + "with_rw_directory", + "with_rw_repo", + "with_rw_and_rw_remote_repo", + "TestBase", + "VirtualEnvironment", + "TestCase", + "SkipTest", + "skipIf", + "GIT_REPO", + "GIT_DAEMON_PORT", +] + import contextlib from functools import wraps import gc @@ -31,22 +47,6 @@ GIT_REPO = os.environ.get("GIT_PYTHON_TEST_GIT_REPO_BASE", ospd(ospd(ospd(__file__)))) GIT_DAEMON_PORT = os.environ.get("GIT_PYTHON_TEST_GIT_DAEMON_PORT", "19418") -__all__ = ( - "fixture_path", - "fixture", - "StringProcessAdapter", - "with_rw_directory", - "with_rw_repo", - "with_rw_and_rw_remote_repo", - "TestBase", - "VirtualEnvironment", - "TestCase", - "SkipTest", - "skipIf", - "GIT_REPO", - "GIT_DAEMON_PORT", -) - _logger = logging.getLogger(__name__) # { Routines diff --git a/test/performance/__init__.py b/test/performance/__init__.py index e69de29bb..56b5d89db 100644 --- a/test/performance/__init__.py +++ b/test/performance/__init__.py @@ -0,0 +1,2 @@ +# This module is part of GitPython and is released under the +# 3-Clause BSD License: https://opensource.org/license/bsd-3-clause/ diff --git a/test/performance/lib.py b/test/performance/lib.py index d08e1027f..2ca3c409b 100644 --- a/test/performance/lib.py +++ b/test/performance/lib.py @@ -5,13 +5,14 @@ import logging import os +import os.path as osp import tempfile from git import Repo from git.db import GitCmdObjectDB, GitDB -from test.lib import TestBase from git.util import rmtree -import os.path as osp + +from test.lib import TestBase # { Invariants diff --git a/test/performance/test_commit.py b/test/performance/test_commit.py index 00d768f0a..b943f1975 100644 --- a/test/performance/test_commit.py +++ b/test/performance/test_commit.py @@ -10,9 +10,11 @@ from time import time import sys -from .lib import TestBigRepoRW -from git import Commit from gitdb import IStream + +from git import Commit + +from test.performance.lib import TestBigRepoRW from test.test_commit import TestCommitSerialization diff --git a/test/performance/test_odb.py b/test/performance/test_odb.py index 00e245fb7..fdbbeb8c3 100644 --- a/test/performance/test_odb.py +++ b/test/performance/test_odb.py @@ -6,7 +6,7 @@ import sys from time import time -from .lib import TestBigRepoR +from test.performance.lib import TestBigRepoR class TestObjDBPerformance(TestBigRepoR): diff --git a/test/performance/test_streams.py b/test/performance/test_streams.py index 56b5274ec..f6ffeba8e 100644 --- a/test/performance/test_streams.py +++ b/test/performance/test_streams.py @@ -5,18 +5,18 @@ import gc import os +import os.path as osp import subprocess import sys from time import time -from test.lib import with_rw_repo -from git.util import bin_to_hex from gitdb import LooseObjectDB, IStream from gitdb.test.lib import make_memory_file -import os.path as osp +from git.util import bin_to_hex -from .lib import TestBigRepoR +from test.lib import with_rw_repo +from test.performance.lib import TestBigRepoR class TestObjDBPerformance(TestBigRepoR): diff --git a/test/test_actor.py b/test/test_actor.py index caf095739..5e6635709 100644 --- a/test/test_actor.py +++ b/test/test_actor.py @@ -3,9 +3,10 @@ # This module is part of GitPython and is released under the # 3-Clause BSD License: https://opensource.org/license/bsd-3-clause/ -from test.lib import TestBase from git import Actor +from test.lib import TestBase + class TestActor(TestBase): def test_from_string_should_separate_name_and_email(self): diff --git a/test/test_base.py b/test/test_base.py index e477b4837..86bcc5c79 100644 --- a/test/test_base.py +++ b/test/test_base.py @@ -5,18 +5,18 @@ import gc import os +import os.path as osp import sys import tempfile from unittest import skipIf from git import Repo -from git.objects import Blob, Tree, Commit, TagObject +from git.objects import Blob, Commit, TagObject, Tree +import git.objects.base as base from git.objects.util import get_object_type_by_name -from test.lib import TestBase as _TestBase, with_rw_repo, with_rw_and_rw_remote_repo -from git.util import hex_to_bin, HIDE_WINDOWS_FREEZE_ERRORS +from git.util import HIDE_WINDOWS_FREEZE_ERRORS, hex_to_bin -import git.objects.base as base -import os.path as osp +from test.lib import TestBase as _TestBase, with_rw_and_rw_remote_repo, with_rw_repo class TestBase(_TestBase): diff --git a/test/test_blob.py b/test/test_blob.py index ff59c67ea..affaa60fc 100644 --- a/test/test_blob.py +++ b/test/test_blob.py @@ -3,9 +3,10 @@ # This module is part of GitPython and is released under the # 3-Clause BSD License: https://opensource.org/license/bsd-3-clause/ -from test.lib import TestBase from git import Blob +from test.lib import TestBase + class TestBlob(TestBase): def test_mime_type_should_return_mime_type_for_known_types(self): diff --git a/test/test_clone.py b/test/test_clone.py index be2e6b19b..126ef0063 100644 --- a/test/test_clone.py +++ b/test/test_clone.py @@ -6,10 +6,7 @@ import git -from .lib import ( - TestBase, - with_rw_directory, -) +from test.lib import TestBase, with_rw_directory class TestClone(TestBase): diff --git a/test/test_commit.py b/test/test_commit.py index 5571b9ecb..5832258de 100644 --- a/test/test_commit.py +++ b/test/test_commit.py @@ -6,23 +6,25 @@ import copy from datetime import datetime from io import BytesIO +import os.path as osp import re import sys import time from unittest.mock import Mock -from git import ( - Commit, - Actor, -) -from git import Repo +from gitdb import IStream + +from git import Actor, Commit, Repo from git.objects.util import tzoffset, utc from git.repo.fun import touch -from test.lib import TestBase, with_rw_repo, fixture_path, StringProcessAdapter -from test.lib import with_rw_directory -from gitdb import IStream -import os.path as osp +from test.lib import ( + StringProcessAdapter, + TestBase, + fixture_path, + with_rw_directory, + with_rw_repo, +) class TestCommitSerialization(TestBase): diff --git a/test/test_config.py b/test/test_config.py index ac19a7fa8..0911d0262 100644 --- a/test/test_config.py +++ b/test/test_config.py @@ -15,8 +15,8 @@ from git import GitConfigParser from git.config import _OMD, cp from git.util import rmfile -from test.lib import SkipTest, TestCase, fixture_path, with_rw_directory +from test.lib import SkipTest, TestCase, fixture_path, with_rw_directory _tc_lock_fpaths = osp.join(osp.dirname(__file__), "fixtures/*.lock") diff --git a/test/test_db.py b/test/test_db.py index de093cbd8..72d63b44b 100644 --- a/test/test_db.py +++ b/test/test_db.py @@ -3,12 +3,13 @@ # This module is part of GitPython and is released under the # 3-Clause BSD License: https://opensource.org/license/bsd-3-clause/ +import os.path as osp + from git.db import GitCmdObjectDB from git.exc import BadObject -from test.lib import TestBase from git.util import bin_to_hex -import os.path as osp +from test.lib import TestBase class TestDB(TestBase): diff --git a/test/test_diff.py b/test/test_diff.py index 96fbc60e3..928a9f428 100644 --- a/test/test_diff.py +++ b/test/test_diff.py @@ -14,6 +14,7 @@ from git import NULL_TREE, Diff, DiffIndex, Diffable, GitCommandError, Repo, Submodule from git.cmd import Git + from test.lib import StringProcessAdapter, TestBase, fixture, with_rw_directory diff --git a/test/test_docs.py b/test/test_docs.py index 409f66bb3..b3547c1de 100644 --- a/test/test_docs.py +++ b/test/test_docs.py @@ -5,6 +5,7 @@ import gc import os +import os.path import sys import pytest @@ -12,8 +13,6 @@ from test.lib import TestBase from test.lib.helper import with_rw_directory -import os.path - class Tutorials(TestBase): def tearDown(self): diff --git a/test/test_exc.py b/test/test_exc.py index 3f4d0b803..c1eae7240 100644 --- a/test/test_exc.py +++ b/test/test_exc.py @@ -3,9 +3,11 @@ # This module is part of GitPython and is released under the # 3-Clause BSD License: https://opensource.org/license/bsd-3-clause/ +from itertools import product import re import ddt + from git.exc import ( InvalidGitRepositoryError, WorkTreeRepositoryUnsupported, @@ -20,9 +22,8 @@ RepositoryDirtyError, ) from git.util import remove_password_if_present -from test.lib import TestBase -import itertools as itt +from test.lib import TestBase _cmd_argvs = ( @@ -79,7 +80,7 @@ def test_ExceptionsHaveBaseClass(self): for ex_class in exception_classes: self.assertTrue(issubclass(ex_class, GitError)) - @ddt.data(*list(itt.product(_cmd_argvs, _causes_n_substrings, _streams_n_substrings))) + @ddt.data(*list(product(_cmd_argvs, _causes_n_substrings, _streams_n_substrings))) def test_CommandError_unicode(self, case): argv, (cause, subs), stream = case cls = CommandError diff --git a/test/test_fun.py b/test/test_fun.py index 2d30d355a..b8593b400 100644 --- a/test/test_fun.py +++ b/test/test_fun.py @@ -2,27 +2,26 @@ # 3-Clause BSD License: https://opensource.org/license/bsd-3-clause/ from io import BytesIO -from stat import S_IFDIR, S_IFREG, S_IFLNK, S_IXUSR +from stat import S_IFDIR, S_IFLNK, S_IFREG, S_IXUSR from os import stat import os.path as osp +from gitdb.base import IStream +from gitdb.typ import str_tree_type + from git import Git from git.index import IndexFile -from git.index.fun import ( - aggressive_tree_merge, - stat_mode_to_index_mode, -) +from git.index.fun import aggressive_tree_merge, stat_mode_to_index_mode from git.objects.fun import ( traverse_tree_recursive, traverse_trees_recursive, - tree_to_stream, tree_entries_from_data, + tree_to_stream, ) from git.repo.fun import find_worktree_git_dir -from test.lib import TestBase, with_rw_repo, with_rw_directory from git.util import bin_to_hex, cygpath, join_path_native -from gitdb.base import IStream -from gitdb.typ import str_tree_type + +from test.lib import TestBase, with_rw_directory, with_rw_repo class TestFun(TestBase): diff --git a/test/test_git.py b/test/test_git.py index dae0f6a39..112e2f0eb 100644 --- a/test/test_git.py +++ b/test/test_git.py @@ -25,8 +25,9 @@ import ddt -from git import Git, refresh, GitCommandError, GitCommandNotFound, Repo, cmd +from git import Git, GitCommandError, GitCommandNotFound, Repo, cmd, refresh from git.util import cwd, finalize_process + from test.lib import TestBase, fixture_path, with_rw_directory diff --git a/test/test_imports.py b/test/test_imports.py new file mode 100644 index 000000000..8e70c6689 --- /dev/null +++ b/test/test_imports.py @@ -0,0 +1,32 @@ +# This module is part of GitPython and is released under the +# 3-Clause BSD License: https://opensource.org/license/bsd-3-clause/ + +import sys + +import git + + +def test_git_util_attribute_is_git_index_util(): + """The top-level module's ``util`` attribute is really :mod:`git.index.util`. + + Although this situation is unintuitive and not a design goal, this has historically + been the case, and it should not be changed without considering the effect on + backward compatibility. In practice, it cannot be changed at least until the next + major version of GitPython. This test checks that it is not accidentally changed, + which could happen when refactoring imports. + """ + assert git.util is git.index.util + + +def test_git_index_util_attribute_is_git_index_util(): + """Nothing unusual is happening with git.index.util itself.""" + assert git.index.util is sys.modules["git.index.util"] + + +def test_separate_git_util_module_exists(): + """The real git.util and git.index.util modules really are separate. + + The real git.util module can be accessed to import a name ``...` by writing + ``from git.util import ...``, and the module object can be accessed in sys.modules. + """ + assert sys.modules["git.util"] is not sys.modules["git.index.util"] diff --git a/test/test_index.py b/test/test_index.py index 622e7ca9a..b92258c92 100644 --- a/test/test_index.py +++ b/test/test_index.py @@ -17,18 +17,12 @@ import sys import tempfile +from gitdb.base import IStream + import ddt import pytest -from git import ( - BlobFilter, - Diff, - Git, - IndexFile, - Object, - Repo, - Tree, -) +from git import BlobFilter, Diff, Git, IndexFile, Object, Repo, Tree from git.exc import ( CheckoutError, GitCommandError, @@ -41,7 +35,7 @@ from git.index.util import TemporaryFileSwap from git.objects import Blob from git.util import Actor, cwd, hex_to_bin, rmtree -from gitdb.base import IStream + from test.lib import ( TestBase, VirtualEnvironment, diff --git a/test/test_reflog.py b/test/test_reflog.py index 1bd2e5dab..7ce64219a 100644 --- a/test/test_reflog.py +++ b/test/test_reflog.py @@ -5,9 +5,10 @@ import tempfile from git.objects import IndexObject -from git.refs import RefLogEntry, RefLog +from git.refs import RefLog, RefLogEntry +from git.util import Actor, hex_to_bin, rmtree + from test.lib import TestBase, fixture_path -from git.util import Actor, rmtree, hex_to_bin class TestRefLog(TestBase): diff --git a/test/test_refs.py b/test/test_refs.py index 28db70c6e..08096e69e 100644 --- a/test/test_refs.py +++ b/test/test_refs.py @@ -4,27 +4,28 @@ # 3-Clause BSD License: https://opensource.org/license/bsd-3-clause/ from itertools import chain +import os.path as osp from pathlib import Path +import tempfile + +from gitdb.exc import BadName from git import ( - Reference, - Head, - TagReference, - RemoteReference, Commit, - SymbolicReference, GitCommandError, - RefLog, GitConfigParser, + Head, + RefLog, + Reference, + RemoteReference, + SymbolicReference, + TagReference, ) from git.objects.tag import TagObject -from test.lib import TestBase, with_rw_repo +import git.refs as refs from git.util import Actor -from gitdb.exc import BadName -import git.refs as refs -import os.path as osp -import tempfile +from test.lib import TestBase, with_rw_repo class TestRefs(TestBase): diff --git a/test/test_remote.py b/test/test_remote.py index f84452deb..5ddb41bc0 100644 --- a/test/test_remote.py +++ b/test/test_remote.py @@ -28,7 +28,7 @@ ) from git.cmd import Git from git.exc import UnsafeOptionError, UnsafeProtocolError -from git.util import rmtree, HIDE_WINDOWS_FREEZE_ERRORS, IterableList +from git.util import HIDE_WINDOWS_FREEZE_ERRORS, IterableList, rmtree from test.lib import ( GIT_DAEMON_PORT, TestBase, @@ -37,7 +37,6 @@ with_rw_repo, ) - # Make sure we have repeatable results. random.seed(0) diff --git a/test/test_repo.py b/test/test_repo.py index 238f94712..e38da5bb6 100644 --- a/test/test_repo.py +++ b/test/test_repo.py @@ -36,13 +36,10 @@ Submodule, Tree, ) -from git.exc import ( - BadObject, - UnsafeOptionError, - UnsafeProtocolError, -) +from git.exc import BadObject, UnsafeOptionError, UnsafeProtocolError from git.repo.fun import touch from git.util import bin_to_hex, cwd, cygpath, join_path_native, rmfile, rmtree + from test.lib import TestBase, fixture, with_rw_directory, with_rw_repo diff --git a/test/test_stats.py b/test/test_stats.py index 4efb6f313..eec73c802 100644 --- a/test/test_stats.py +++ b/test/test_stats.py @@ -3,10 +3,11 @@ # This module is part of GitPython and is released under the # 3-Clause BSD License: https://opensource.org/license/bsd-3-clause/ -from test.lib import TestBase, fixture from git import Stats from git.compat import defenc +from test.lib import TestBase, fixture + class TestStats(TestBase): def test_list_from_string(self): diff --git a/test/test_submodule.py b/test/test_submodule.py index ee7795dbb..d88f9dab0 100644 --- a/test/test_submodule.py +++ b/test/test_submodule.py @@ -27,6 +27,7 @@ from git.objects.submodule.root import RootModule, RootUpdateProgress from git.repo.fun import find_submodule_git_dir, touch from git.util import HIDE_WINDOWS_KNOWN_ERRORS, join_path_native, to_native_path_linux + from test.lib import TestBase, with_rw_directory, with_rw_repo diff --git a/test/test_tree.py b/test/test_tree.py index 0c06b950c..73158113d 100644 --- a/test/test_tree.py +++ b/test/test_tree.py @@ -8,8 +8,9 @@ from pathlib import Path import subprocess -from git.objects import Tree, Blob +from git.objects import Blob, Tree from git.util import cwd + from test.lib import TestBase, with_rw_directory diff --git a/test/test_util.py b/test/test_util.py index 369896581..dad2f3dcd 100644 --- a/test/test_util.py +++ b/test/test_util.py @@ -38,6 +38,7 @@ remove_password_if_present, rmtree, ) + from test.lib import TestBase, with_rw_repo