diff options
-rw-r--r-- | git/cmd.py | 16 | ||||
-rw-r--r-- | git/compat.py | 18 | ||||
-rw-r--r-- | git/config.py | 11 | ||||
-rw-r--r-- | git/diff.py | 5 | ||||
-rw-r--r-- | git/index/base.py | 11 | ||||
-rw-r--r-- | git/objects/submodule/base.py | 3 | ||||
-rw-r--r-- | git/refs/reference.py | 2 | ||||
-rw-r--r-- | git/refs/symbolic.py | 4 | ||||
-rw-r--r-- | git/remote.py | 10 | ||||
-rw-r--r-- | git/repo/base.py | 9 | ||||
-rw-r--r-- | git/util.py | 5 |
11 files changed, 41 insertions, 53 deletions
@@ -68,7 +68,7 @@ __all__ = ('Git',) # Documentation ## @{ -def handle_process_output(process: subprocess.Popen, +def handle_process_output(process: Union[subprocess.Popen, 'Git.AutoInterrupt'], stdout_handler: Union[None, Callable[[AnyStr], None], Callable[[List[AnyStr]], None], @@ -77,7 +77,7 @@ def handle_process_output(process: subprocess.Popen, Callable[[AnyStr], None], Callable[[List[AnyStr]], None]], finalizer: Union[None, - Callable[[subprocess.Popen], None]] = None, + Callable[[Union[subprocess.Popen, 'Git.AutoInterrupt']], None]] = None, decode_streams: bool = True) -> None: """Registers for notifications to learn that process output is ready to read, and dispatches lines to the respective line handlers. @@ -421,15 +421,15 @@ class Git(LazyMixin): return getattr(self.proc, attr) # TODO: Bad choice to mimic `proc.wait()` but with different args. - def wait(self, stderr: Union[None, bytes] = b'') -> int: + def wait(self, stderr: Union[None, str, bytes] = b'') -> int: """Wait for the process and return its status code. :param stderr: Previously read value of stderr, in case stderr is already closed. :warn: may deadlock if output or error pipes are used and not handled separately. :raise GitCommandError: if the return status is not 0""" if stderr is None: - stderr = b'' - stderr = force_bytes(data=stderr, encoding='utf-8') + stderr_b = b'' + stderr_b = force_bytes(data=stderr, encoding='utf-8') if self.proc is not None: status = self.proc.wait() @@ -437,11 +437,11 @@ class Git(LazyMixin): def read_all_from_possibly_closed_stream(stream: Union[IO[bytes], None]) -> bytes: if stream: try: - return stderr + force_bytes(stream.read()) + return stderr_b + force_bytes(stream.read()) except ValueError: - return stderr or b'' + return stderr_b or b'' else: - return stderr or b'' + return stderr_b or b'' if status != 0: errstr = read_all_from_possibly_closed_stream(self.proc.stderr) diff --git a/git/compat.py b/git/compat.py index 7a0a15d2..988c04ef 100644 --- a/git/compat.py +++ b/git/compat.py @@ -29,8 +29,6 @@ from typing import ( Union, overload, ) -from git.types import TBD - # --------------------------------------------------------------------------- @@ -97,19 +95,3 @@ def win_encode(s: Optional[AnyStr]) -> Optional[bytes]: elif s is not None: raise TypeError('Expected bytes or text, but got %r' % (s,)) return None - - -# type: ignore ## mypy cannot understand dynamic class creation -def with_metaclass(meta: Type[Any], *bases: Any) -> TBD: - """copied from https://github.com/Byron/bcore/blob/master/src/python/butility/future.py#L15""" - - class metaclass(meta): # type: ignore - __call__ = type.__call__ - __init__ = type.__init__ # type: ignore - - def __new__(cls, name: str, nbases: Optional[Tuple[int, ...]], d: Dict[str, Any]) -> TBD: - if nbases is None: - return type.__new__(cls, name, (), d) - return meta(name, bases, d) - - return metaclass(meta.__name__ + 'Helper', None, {}) # type: ignore diff --git a/git/config.py b/git/config.py index 011d0e0b..3565eece 100644 --- a/git/config.py +++ b/git/config.py @@ -33,7 +33,7 @@ import configparser as cp from typing import (Any, Callable, Generic, IO, List, Dict, Sequence, TYPE_CHECKING, Tuple, TypeVar, Union, cast, overload) -from git.types import Lit_config_levels, ConfigLevels_Tup, PathLike, TBD, assert_never, _T +from git.types import Lit_config_levels, ConfigLevels_Tup, PathLike, assert_never, _T if TYPE_CHECKING: from git.repo.base import Repo @@ -72,7 +72,7 @@ CONDITIONAL_INCLUDE_REGEXP = re.compile(r"(?<=includeIf )\"(gitdir|gitdir/i|onbr class MetaParserBuilder(abc.ABCMeta): """Utlity class wrapping base-class methods into decorators that assure read-only properties""" - def __new__(cls, name: str, bases: TBD, clsdict: Dict[str, Any]) -> TBD: + def __new__(cls, name: str, bases: Tuple, clsdict: Dict[str, Any]) -> 'MetaParserBuilder': """ Equip all base-class methods with a needs_values decorator, and all non-const methods with a set_dirty_and_flush_changes decorator in addition to that.""" @@ -617,12 +617,12 @@ class GitConfigParser(cp.RawConfigParser, metaclass=MetaParserBuilder): def write_section(name: str, section_dict: _OMD) -> None: fp.write(("[%s]\n" % name).encode(defenc)) - values: Sequence[Union[str, bytes, int, float, bool]] + values: Sequence[str] # runtime only gets str in tests, but should be whatever _OMD stores + v: str for (key, values) in section_dict.items_all(): if key == "__name__": continue - v: Union[str, bytes, int, float, bool] for v in values: fp.write(("\t%s = %s\n" % (key, self._value_to_string(v).replace('\n', '\n\t'))).encode(defenc)) # END if key is not __name__ @@ -630,7 +630,8 @@ class GitConfigParser(cp.RawConfigParser, metaclass=MetaParserBuilder): if self._defaults: write_section(cp.DEFAULTSECT, self._defaults) - value: TBD + value: _OMD + for name, value in self._sections.items(): write_section(name, value) diff --git a/git/diff.py b/git/diff.py index 74ca0b64..fc16b73e 100644 --- a/git/diff.py +++ b/git/diff.py @@ -16,7 +16,7 @@ from .objects.util import mode_str_to_int # typing ------------------------------------------------------------------ from typing import Any, Iterator, List, Match, Optional, Tuple, Type, TypeVar, Union, TYPE_CHECKING, cast -from git.types import PathLike, TBD, Literal +from git.types import PathLike, Literal if TYPE_CHECKING: from .objects.tree import Tree @@ -24,6 +24,7 @@ if TYPE_CHECKING: 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'] @@ -442,7 +443,7 @@ class Diff(object): return None @ classmethod - def _index_from_patch_format(cls, repo: 'Repo', proc: TBD) -> DiffIndex: + def _index_from_patch_format(cls, repo: 'Repo', proc: Union['Popen', 'Git.AutoInterrupt']) -> DiffIndex: """Create a new DiffIndex from the given text which must be in patch format :param repo: is the repository we are operating on - it is required :param stream: result of 'git diff' as a stream (supporting file protocol) diff --git a/git/index/base.py b/git/index/base.py index 6452419c..4c8b923a 100644 --- a/git/index/base.py +++ b/git/index/base.py @@ -70,7 +70,7 @@ from .util import ( from typing import (Any, BinaryIO, Callable, Dict, IO, Iterable, Iterator, List, NoReturn, Sequence, TYPE_CHECKING, Tuple, Type, Union) -from git.types import Commit_ish, PathLike, TBD +from git.types import Commit_ish, PathLike if TYPE_CHECKING: from subprocess import Popen @@ -181,7 +181,7 @@ class IndexFile(LazyMixin, git_diff.Diffable, Serializable): self.version, self.entries, self._extension_data, _conten_sha = read_cache(stream) return self - def _entries_sorted(self) -> List[TBD]: + def _entries_sorted(self) -> List[IndexEntry]: """:return: list of entries, in a sorted fashion, first by path, then by stage""" return sorted(self.entries.values(), key=lambda e: (e.path, e.stage)) @@ -427,8 +427,8 @@ class IndexFile(LazyMixin, git_diff.Diffable, Serializable): # END path exception handling # END for each path - def _write_path_to_stdin(self, proc: 'Popen', filepath: PathLike, item: TBD, fmakeexc: Callable[..., GitError], - fprogress: Callable[[PathLike, bool, TBD], None], + def _write_path_to_stdin(self, proc: 'Popen', filepath: PathLike, item: PathLike, fmakeexc: Callable[..., GitError], + fprogress: Callable[[PathLike, bool, PathLike], None], read_from_stdout: bool = True) -> Union[None, str]: """Write path to proc.stdin and make sure it processes the item, including progress. @@ -492,12 +492,13 @@ class IndexFile(LazyMixin, git_diff.Diffable, Serializable): are at stage 3 will not have a stage 3 entry. """ is_unmerged_blob = lambda t: t[0] != 0 - path_map: Dict[PathLike, List[Tuple[TBD, Blob]]] = {} + path_map: Dict[PathLike, List[Tuple[StageType, Blob]]] = {} for stage, blob in self.iter_blobs(is_unmerged_blob): path_map.setdefault(blob.path, []).append((stage, blob)) # END for each unmerged blob for line in path_map.values(): line.sort() + return path_map @ classmethod diff --git a/git/objects/submodule/base.py b/git/objects/submodule/base.py index 559d2585..d306c91d 100644 --- a/git/objects/submodule/base.py +++ b/git/objects/submodule/base.py @@ -379,6 +379,7 @@ class Submodule(IndexObject, TraversableIterableObj): :return: The newly created submodule instance :note: works atomically, such that no change will be done if the repository update fails for instance""" + if repo.bare: raise InvalidGitRepositoryError("Cannot add submodules to bare repositories") # END handle bare repos @@ -434,7 +435,7 @@ class Submodule(IndexObject, TraversableIterableObj): url = urls[0] else: # clone new repo - kwargs: Dict[str, Union[bool, int, Sequence[TBD]]] = {'n': no_checkout} + kwargs: Dict[str, Union[bool, int, str, Sequence[TBD]]] = {'n': no_checkout} if not branch_is_default: kwargs['b'] = br.name # END setup checkout-branch diff --git a/git/refs/reference.py b/git/refs/reference.py index a3647fb3..2a33fbff 100644 --- a/git/refs/reference.py +++ b/git/refs/reference.py @@ -8,7 +8,7 @@ from .symbolic import SymbolicReference, T_References # typing ------------------------------------------------------------------ from typing import Any, Callable, Iterator, Type, Union, TYPE_CHECKING # NOQA -from git.types import Commit_ish, PathLike, TBD, Literal, _T # NOQA +from git.types import Commit_ish, PathLike, _T # NOQA if TYPE_CHECKING: from git.repo import Repo diff --git a/git/refs/symbolic.py b/git/refs/symbolic.py index b4a933aa..1c56c043 100644 --- a/git/refs/symbolic.py +++ b/git/refs/symbolic.py @@ -21,8 +21,8 @@ from .log import RefLog # typing ------------------------------------------------------------------ -from typing import Any, Iterator, List, Match, Optional, Tuple, Type, TypeVar, Union, TYPE_CHECKING, cast # NOQA -from git.types import Commit_ish, PathLike, TBD, Literal # NOQA +from typing import Any, Iterator, List, Tuple, Type, TypeVar, Union, TYPE_CHECKING, cast # NOQA +from git.types import Commit_ish, PathLike # NOQA if TYPE_CHECKING: from git.repo import Repo diff --git a/git/remote.py b/git/remote.py index 11007cb6..c141519a 100644 --- a/git/remote.py +++ b/git/remote.py @@ -37,10 +37,10 @@ from .refs import ( # typing------------------------------------------------------- -from typing import (Any, Callable, Dict, Iterator, List, NoReturn, Optional, Sequence, # NOQA[TC002] +from typing import (Any, Callable, Dict, Iterator, List, NoReturn, Optional, Sequence, TYPE_CHECKING, Type, Union, cast, overload) -from git.types import PathLike, Literal, TBD, Commit_ish # NOQA[TC002] +from git.types import PathLike, Literal, Commit_ish if TYPE_CHECKING: from git.repo.base import Repo @@ -50,7 +50,6 @@ if TYPE_CHECKING: flagKeyLiteral = Literal[' ', '!', '+', '-', '*', '=', 't', '?'] - # def is_flagKeyLiteral(inp: str) -> TypeGuard[flagKeyLiteral]: # return inp in [' ', '!', '+', '-', '=', '*', 't', '?'] @@ -707,9 +706,10 @@ class Remote(LazyMixin, IterableObj): self.repo.git.remote(scmd, self.name, **kwargs) return self - def _get_fetch_info_from_stderr(self, proc: TBD, + def _get_fetch_info_from_stderr(self, proc: 'Git.AutoInterrupt', progress: Union[Callable[..., Any], RemoteProgress, None] ) -> IterableList['FetchInfo']: + progress = to_progress_instance(progress) # skip first line as it is some remote info we are not interested in @@ -768,7 +768,7 @@ class Remote(LazyMixin, IterableObj): log.warning("Git informed while fetching: %s", err_line.strip()) return output - def _get_push_info(self, proc: TBD, + def _get_push_info(self, proc: 'Git.AutoInterrupt', progress: Union[Callable[..., Any], RemoteProgress, None]) -> IterableList[PushInfo]: progress = to_progress_instance(progress) diff --git a/git/repo/base.py b/git/repo/base.py index 5581233b..07cf7adf 100644 --- a/git/repo/base.py +++ b/git/repo/base.py @@ -235,7 +235,7 @@ class Repo(object): def __enter__(self) -> 'Repo': return self - def __exit__(self, exc_type: TBD, exc_value: TBD, traceback: TBD) -> None: + def __exit__(self, *args: Any) -> None: self.close() def __del__(self) -> None: @@ -445,7 +445,7 @@ class Repo(object): :return: TagReference object """ return TagReference.create(self, path, ref, message, force, **kwargs) - def delete_tag(self, *tags: TBD) -> None: + def delete_tag(self, *tags: TagReference) -> None: """Delete the given tag references""" return TagReference.delete(self, *tags) @@ -795,7 +795,7 @@ class Repo(object): # reveal_type(self.head.reference) # => Reference return self.head.reference - def blame_incremental(self, rev: TBD, file: TBD, **kwargs: Any) -> Optional[Iterator['BlameEntry']]: + def blame_incremental(self, rev: Union[str, HEAD], file: str, **kwargs: Any) -> Iterator['BlameEntry']: """Iterator for blame information for the given file at the given revision. Unlike .blame(), this does not return the actual file's contents, only @@ -809,6 +809,7 @@ class Repo(object): If you combine all line number ranges outputted by this command, you should get a continuous range spanning all line numbers in the file. """ + data = self.git.blame(rev, '--', file, p=True, incremental=True, stdout_as_string=False, **kwargs) commits: Dict[str, Commit] = {} @@ -870,7 +871,7 @@ class Repo(object): safe_decode(orig_filename), range(orig_lineno, orig_lineno + num_lines)) - def blame(self, rev: TBD, file: TBD, incremental: bool = False, **kwargs: Any + def blame(self, rev: Union[str, HEAD], file: str, incremental: bool = False, **kwargs: Any ) -> Union[List[List[Union[Optional['Commit'], List[str]]]], Optional[Iterator[BlameEntry]]]: """The blame information for the given file at the given revision. diff --git a/git/util.py b/git/util.py index 92d95379..8056804a 100644 --- a/git/util.py +++ b/git/util.py @@ -38,6 +38,7 @@ if TYPE_CHECKING: from git.remote import Remote from git.repo.base import Repo from git.config import GitConfigParser, SectionConstraint + from git import Git # from git.objects.base import IndexObject @@ -379,7 +380,7 @@ def get_user_id() -> str: return "%s@%s" % (getpass.getuser(), platform.node()) -def finalize_process(proc: subprocess.Popen, **kwargs: Any) -> None: +def finalize_process(proc: Union[subprocess.Popen, 'Git.AutoInterrupt'], **kwargs: Any) -> None: """Wait for the process (clone, fetch, pull or push) and handle its errors accordingly""" # TODO: No close proc-streams?? proc.wait(**kwargs) @@ -1033,7 +1034,7 @@ class IterableList(List[T_IterableObj]): class IterableClassWatcher(type): """ Metaclass that watches """ - def __init__(cls, name: str, bases: List, clsdict: Dict) -> None: + def __init__(cls, name: str, bases: Tuple, clsdict: Dict) -> None: for base in bases: if type(base) == IterableClassWatcher: warnings.warn(f"GitPython Iterable subclassed by {name}. " |