summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.flake82
-rw-r--r--git/config.py69
-rw-r--r--git/diff.py14
-rw-r--r--git/index/fun.py28
-rw-r--r--git/index/typ.py84
-rw-r--r--git/objects/commit.py21
-rw-r--r--git/objects/submodule/base.py14
-rw-r--r--git/objects/submodule/util.py2
-rw-r--r--git/objects/tree.py6
-rw-r--r--git/refs/reference.py2
-rw-r--r--git/refs/symbolic.py2
-rw-r--r--git/remote.py15
-rw-r--r--git/repo/base.py11
-rw-r--r--git/types.py17
-rw-r--r--requirements.txt2
15 files changed, 140 insertions, 149 deletions
diff --git a/.flake8 b/.flake8
index 3cf342f9..2f9e6ed2 100644
--- a/.flake8
+++ b/.flake8
@@ -20,7 +20,7 @@ ignore = E265,E266,E731,E704,
W293, W504,
ANN0 ANN1 ANN2,
TC002,
- # TC0, TC1, TC2
+ TC0, TC1, TC2
# B,
A,
D,
diff --git a/git/config.py b/git/config.py
index 345cb40e..c4b26ba6 100644
--- a/git/config.py
+++ b/git/config.py
@@ -6,6 +6,7 @@
"""Module containing module parser implementation able to properly read and write
configuration files"""
+import sys
import abc
from functools import wraps
import inspect
@@ -14,12 +15,10 @@ import logging
import os
import re
import fnmatch
-from collections import OrderedDict
from git.compat import (
defenc,
force_text,
- with_metaclass,
is_win,
)
@@ -31,15 +30,24 @@ import configparser as cp
# typing-------------------------------------------------------
-from typing import (Any, Callable, IO, List, Dict, Sequence,
- TYPE_CHECKING, Tuple, Union, cast, overload)
+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, is_config_level
+from git.types import Lit_config_levels, ConfigLevels_Tup, PathLike, TBD, assert_never, _T
if TYPE_CHECKING:
from git.repo.base import Repo
from io import BytesIO
+T_ConfigParser = TypeVar('T_ConfigParser', bound='GitConfigParser')
+
+if sys.version_info[:2] < (3, 7):
+ from collections import OrderedDict
+ OrderedDict_OMD = OrderedDict
+else:
+ from typing import OrderedDict
+ OrderedDict_OMD = OrderedDict[str, List[_T]]
+
# -------------------------------------------------------------
__all__ = ('GitConfigParser', 'SectionConstraint')
@@ -61,7 +69,6 @@ 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:
"""
@@ -115,7 +122,7 @@ def set_dirty_and_flush_changes(non_const_func: Callable) -> Callable:
return flush_changes
-class SectionConstraint(object):
+class SectionConstraint(Generic[T_ConfigParser]):
"""Constrains a ConfigParser to only option commands which are constrained to
always use the section we have been initialized with.
@@ -128,7 +135,7 @@ class SectionConstraint(object):
_valid_attrs_ = ("get_value", "set_value", "get", "set", "getint", "getfloat", "getboolean", "has_option",
"remove_section", "remove_option", "options")
- def __init__(self, config: 'GitConfigParser', section: str) -> None:
+ def __init__(self, config: T_ConfigParser, section: str) -> None:
self._config = config
self._section_name = section
@@ -149,7 +156,7 @@ class SectionConstraint(object):
return getattr(self._config, method)(self._section_name, *args, **kwargs)
@property
- def config(self) -> 'GitConfigParser':
+ def config(self) -> T_ConfigParser:
"""return: Configparser instance we constrain"""
return self._config
@@ -157,7 +164,7 @@ class SectionConstraint(object):
"""Equivalent to GitConfigParser.release(), which is called on our underlying parser instance"""
return self._config.release()
- def __enter__(self) -> 'SectionConstraint':
+ def __enter__(self) -> 'SectionConstraint[T_ConfigParser]':
self._config.__enter__()
return self
@@ -165,10 +172,10 @@ class SectionConstraint(object):
self._config.__exit__(exception_type, exception_value, traceback)
-class _OMD(OrderedDict):
+class _OMD(OrderedDict_OMD):
"""Ordered multi-dict."""
- def __setitem__(self, key: str, value: Any) -> None:
+ def __setitem__(self, key: str, value: _T) -> None: # type: ignore[override]
super(_OMD, self).__setitem__(key, [value])
def add(self, key: str, value: Any) -> None:
@@ -177,7 +184,7 @@ class _OMD(OrderedDict):
return None
super(_OMD, self).__getitem__(key).append(value)
- def setall(self, key: str, values: Any) -> None:
+ def setall(self, key: str, values: List[_T]) -> None:
super(_OMD, self).__setitem__(key, values)
def __getitem__(self, key: str) -> Any:
@@ -194,25 +201,17 @@ class _OMD(OrderedDict):
prior = super(_OMD, self).__getitem__(key)
prior[-1] = value
- @overload
- def get(self, key: str, default: None = ...) -> None:
- ...
-
- @overload
- def get(self, key: str, default: Any = ...) -> Any:
- ...
-
- def get(self, key: str, default: Union[Any, None] = None) -> Union[Any, None]:
- return super(_OMD, self).get(key, [default])[-1]
+ def get(self, key: str, default: Union[_T, None] = None) -> Union[_T, None]: # type: ignore
+ return super(_OMD, self).get(key, [default])[-1] # type: ignore
- def getall(self, key: str) -> Any:
+ def getall(self, key: str) -> List[_T]:
return super(_OMD, self).__getitem__(key)
- def items(self) -> List[Tuple[str, Any]]: # type: ignore[override]
+ def items(self) -> List[Tuple[str, _T]]: # type: ignore[override]
"""List of (key, last value for key)."""
return [(k, self[k]) for k in self]
- def items_all(self) -> List[Tuple[str, List[Any]]]:
+ def items_all(self) -> List[Tuple[str, List[_T]]]:
"""List of (key, list of values for key)."""
return [(k, self.getall(k)) for k in self]
@@ -238,7 +237,7 @@ def get_config_path(config_level: Lit_config_levels) -> str:
assert_never(config_level, ValueError(f"Invalid configuration level: {config_level!r}"))
-class GitConfigParser(with_metaclass(MetaParserBuilder, cp.RawConfigParser)): # type: ignore ## mypy does not understand dynamic class creation # noqa: E501
+class GitConfigParser(cp.RawConfigParser, metaclass=MetaParserBuilder):
"""Implements specifics required to read git style configuration files.
@@ -298,7 +297,10 @@ class GitConfigParser(with_metaclass(MetaParserBuilder, cp.RawConfigParser)): #
:param repo: Reference to repository to use if [includeIf] sections are found in configuration files.
"""
- cp.RawConfigParser.__init__(self, dict_type=_OMD)
+ cp.RawConfigParser.__init__(self, dict_type=_OMD) # type: ignore[arg-type]
+ self._dict: Callable[..., _OMD] # type: ignore[assignment] # mypy/typeshed bug
+ self._defaults: _OMD # type: ignore[assignment] # mypy/typeshed bug
+ self._sections: _OMD # type: ignore[assignment] # mypy/typeshed bug
# Used in python 3, needs to stay in sync with sections for underlying implementation to work
if not hasattr(self, '_proxies'):
@@ -309,9 +311,9 @@ class GitConfigParser(with_metaclass(MetaParserBuilder, cp.RawConfigParser)): #
else:
if config_level is None:
if read_only:
- self._file_or_files = [get_config_path(f)
+ self._file_or_files = [get_config_path(cast(Lit_config_levels, f))
for f in CONFIG_LEVELS
- if is_config_level(f) and f != 'repository']
+ if f != 'repository']
else:
raise ValueError("No configuration level or configuration files specified")
else:
@@ -424,7 +426,7 @@ class GitConfigParser(with_metaclass(MetaParserBuilder, cp.RawConfigParser)): #
# is it a section header?
mo = self.SECTCRE.match(line.strip())
if not is_multi_line and mo:
- sectname = mo.group('header').strip()
+ sectname: str = mo.group('header').strip()
if sectname in self._sections:
cursect = self._sections[sectname]
elif sectname == cp.DEFAULTSECT:
@@ -535,7 +537,7 @@ class GitConfigParser(with_metaclass(MetaParserBuilder, cp.RawConfigParser)): #
return paths
- def read(self) -> None:
+ def read(self) -> None: # type: ignore[override]
"""Reads the data stored in the files we have been initialized with. It will
ignore files that cannot be read, possibly leaving an empty configuration
@@ -623,10 +625,11 @@ class GitConfigParser(with_metaclass(MetaParserBuilder, cp.RawConfigParser)): #
if self._defaults:
write_section(cp.DEFAULTSECT, self._defaults)
+ value: TBD
for name, value in self._sections.items():
write_section(name, value)
- def items(self, section_name: str) -> List[Tuple[str, str]]:
+ def items(self, section_name: str) -> List[Tuple[str, str]]: # type: ignore[override]
""":return: list((option, value), ...) pairs of all items in the given section"""
return [(k, v) for k, v in super(GitConfigParser, self).items(section_name) if k != '__name__']
diff --git a/git/diff.py b/git/diff.py
index 98a5cfd9..74ca0b64 100644
--- a/git/diff.py
+++ b/git/diff.py
@@ -15,8 +15,8 @@ from .objects.util import mode_str_to_int
# typing ------------------------------------------------------------------
-from typing import Any, Iterator, List, Match, Optional, Tuple, Type, TypeVar, Union, TYPE_CHECKING
-from git.types import PathLike, TBD, Literal, TypeGuard
+from typing import Any, Iterator, List, Match, Optional, Tuple, Type, TypeVar, Union, TYPE_CHECKING, cast
+from git.types import PathLike, TBD, Literal
if TYPE_CHECKING:
from .objects.tree import Tree
@@ -28,9 +28,9 @@ if TYPE_CHECKING:
Lit_change_type = Literal['A', 'D', 'C', 'M', 'R', 'T', 'U']
-def is_change_type(inp: str) -> TypeGuard[Lit_change_type]:
- # return True
- return inp in ['A', 'D', 'C', 'M', 'R', 'T', 'U']
+# def is_change_type(inp: str) -> TypeGuard[Lit_change_type]:
+# # return True
+# return inp in ['A', 'D', 'C', 'M', 'R', 'T', 'U']
# ------------------------------------------------------------------------
@@ -517,8 +517,8 @@ class Diff(object):
# 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 = _change_type[0]
+ # 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
path = path.strip()
diff --git a/git/index/fun.py b/git/index/fun.py
index e071e15c..49e3f2c5 100644
--- a/git/index/fun.py
+++ b/git/index/fun.py
@@ -53,10 +53,11 @@ from .util import (
from typing import (Dict, IO, List, Sequence, TYPE_CHECKING, Tuple, Type, Union, cast)
-from git.types import PathLike, TypeGuard
+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
@@ -149,15 +150,15 @@ def write_cache(entries: Sequence[Union[BaseIndexEntry, 'IndexEntry']], stream:
# body
for entry in entries:
beginoffset = tell()
- write(entry[4]) # ctime
- write(entry[5]) # mtime
- path_str: str = entry[3]
+ write(entry.ctime_bytes) # ctime
+ write(entry.mtime_bytes) # mtime
+ path_str = str(entry.path)
path: bytes = force_bytes(path_str, encoding=defenc)
plen = len(path) & CE_NAMEMASK # path length
- assert plen == len(path), "Path %s too long to fit into index" % entry[3]
- flags = plen | (entry[2] & CE_NAMEMASK_INV) # clear possible previous values
- write(pack(">LLLLLL20sH", entry[6], entry[7], entry[0],
- entry[8], entry[9], entry[10], entry[1], flags))
+ assert plen == len(path), "Path %s too long to fit into index" % entry.path
+ flags = plen | (entry.flags & CE_NAMEMASK_INV) # clear possible previous values
+ write(pack(">LLLLLL20sH", entry.dev, entry.inode, entry.mode,
+ entry.uid, entry.gid, entry.size, entry.binsha, flags))
write(path)
real_size = ((tell() - beginoffset + 8) & ~7)
write(b"\0" * ((beginoffset + real_size) - tell()))
@@ -188,15 +189,16 @@ def entry_key(*entry: Union[BaseIndexEntry, PathLike, int]) -> Tuple[PathLike, i
""":return: Key suitable to be used for the index.entries dictionary
:param entry: One instance of type BaseIndexEntry or the path and the stage"""
- def is_entry_key_tup(entry_key: Tuple) -> TypeGuard[Tuple[PathLike, int]]:
- return isinstance(entry_key, tuple) and len(entry_key) == 2
+ # def is_entry_key_tup(entry_key: Tuple) -> TypeGuard[Tuple[PathLike, int]]:
+ # return isinstance(entry_key, tuple) and len(entry_key) == 2
if len(entry) == 1:
entry_first = entry[0]
assert isinstance(entry_first, BaseIndexEntry)
return (entry_first.path, entry_first.stage)
else:
- assert is_entry_key_tup(entry)
+ # assert is_entry_key_tup(entry)
+ entry = cast(Tuple[PathLike, int], entry)
return entry
# END handle entry
@@ -244,7 +246,7 @@ def read_cache(stream: IO[bytes]) -> Tuple[int, Dict[Tuple[PathLike, int], 'Inde
content_sha = extension_data[-20:]
# truncate the sha in the end as we will dynamically create it anyway
- extension_data = extension_data[:-20]
+ extension_data = extension_data[: -20]
return (version, entries, extension_data, content_sha)
@@ -310,7 +312,7 @@ def _tree_entry_to_baseindexentry(tree_entry: 'TreeCacheTup', stage: int) -> Bas
return BaseIndexEntry((tree_entry[1], tree_entry[0], stage << CE_STAGESHIFT, tree_entry[2]))
-def aggressive_tree_merge(odb, tree_shas: Sequence[bytes]) -> List[BaseIndexEntry]:
+def aggressive_tree_merge(odb: 'GitCmdObjectDB', tree_shas: Sequence[bytes]) -> List[BaseIndexEntry]:
"""
:return: list of BaseIndexEntries representing the aggressive merge of the given
trees. All valid entries are on stage 0, whereas the conflicting ones are left
diff --git a/git/index/typ.py b/git/index/typ.py
index bb1a0384..46f1b077 100644
--- a/git/index/typ.py
+++ b/git/index/typ.py
@@ -11,7 +11,7 @@ from git.objects import Blob
# typing ----------------------------------------------------------------------
-from typing import (List, Sequence, TYPE_CHECKING, Tuple, cast)
+from typing import (NamedTuple, Sequence, TYPE_CHECKING, Tuple, Union, cast)
from git.types import PathLike
@@ -59,14 +59,37 @@ class BlobFilter(object):
return False
-class BaseIndexEntry(tuple):
+class BaseIndexEntryHelper(NamedTuple):
+ """Typed namedtuple to provide named attribute access for BaseIndexEntry.
+ Needed to allow overriding __new__ in child class to preserve backwards compat."""
+ mode: int
+ binsha: bytes
+ flags: int
+ path: PathLike
+ ctime_bytes: bytes = pack(">LL", 0, 0)
+ mtime_bytes: bytes = pack(">LL", 0, 0)
+ dev: int = 0
+ inode: int = 0
+ uid: int = 0
+ gid: int = 0
+ size: int = 0
+
+
+class BaseIndexEntry(BaseIndexEntryHelper):
"""Small Brother of an index entry which can be created to describe changes
done to the index in which case plenty of additional information is not required.
As the first 4 data members match exactly to the IndexEntry type, methods
expecting a BaseIndexEntry can also handle full IndexEntries even if they
- use numeric indices for performance reasons. """
+ use numeric indices for performance reasons.
+ """
+
+ def __new__(cls, inp_tuple: Union[Tuple[int, bytes, int, PathLike],
+ Tuple[int, bytes, int, PathLike, bytes, bytes, int, int, int, int, int]]
+ ) -> 'BaseIndexEntry':
+ """Override __new__ to allow construction from a tuple for backwards compatibility """
+ return super().__new__(cls, *inp_tuple)
def __str__(self) -> str:
return "%o %s %i\t%s" % (self.mode, self.hexsha, self.stage, self.path)
@@ -75,19 +98,9 @@ class BaseIndexEntry(tuple):
return "(%o, %s, %i, %s)" % (self.mode, self.hexsha, self.stage, self.path)
@property
- def mode(self) -> int:
- """ File Mode, compatible to stat module constants """
- return self[0]
-
- @property
- def binsha(self) -> bytes:
- """binary sha of the blob """
- return self[1]
-
- @property
def hexsha(self) -> str:
"""hex version of our sha"""
- return b2a_hex(self[1]).decode('ascii')
+ return b2a_hex(self.binsha).decode('ascii')
@property
def stage(self) -> int:
@@ -100,17 +113,7 @@ class BaseIndexEntry(tuple):
:note: For more information, see http://www.kernel.org/pub/software/scm/git/docs/git-read-tree.html
"""
- return (self[2] & CE_STAGEMASK) >> CE_STAGESHIFT
-
- @property
- def path(self) -> str:
- """:return: our path relative to the repository working tree root"""
- return self[3]
-
- @property
- def flags(self) -> List[str]:
- """:return: flags stored with this entry"""
- return self[2]
+ return (self.flags & CE_STAGEMASK) >> CE_STAGESHIFT
@classmethod
def from_blob(cls, blob: Blob, stage: int = 0) -> 'BaseIndexEntry':
@@ -136,40 +139,15 @@ class IndexEntry(BaseIndexEntry):
:return:
Tuple(int_time_seconds_since_epoch, int_nano_seconds) of the
file's creation time"""
- return cast(Tuple[int, int], unpack(">LL", self[4]))
+ return cast(Tuple[int, int], unpack(">LL", self.ctime_bytes))
@property
def mtime(self) -> Tuple[int, int]:
"""See ctime property, but returns modification time """
- return cast(Tuple[int, int], unpack(">LL", self[5]))
-
- @property
- def dev(self) -> int:
- """ Device ID """
- return self[6]
-
- @property
- def inode(self) -> int:
- """ Inode ID """
- return self[7]
-
- @property
- def uid(self) -> int:
- """ User ID """
- return self[8]
-
- @property
- def gid(self) -> int:
- """ Group ID """
- return self[9]
-
- @property
- def size(self) -> int:
- """:return: Uncompressed size of the blob """
- return self[10]
+ return cast(Tuple[int, int], unpack(">LL", self.mtime_bytes))
@classmethod
- def from_base(cls, base):
+ def from_base(cls, base: 'BaseIndexEntry') -> 'IndexEntry':
"""
:return:
Minimal entry as created from the given BaseIndexEntry instance.
diff --git a/git/objects/commit.py b/git/objects/commit.py
index 11cf52a5..884f6522 100644
--- a/git/objects/commit.py
+++ b/git/objects/commit.py
@@ -39,9 +39,9 @@ import logging
# typing ------------------------------------------------------------------
-from typing import Any, IO, Iterator, List, Sequence, Tuple, Union, TYPE_CHECKING
+from typing import Any, IO, Iterator, List, Sequence, Tuple, Union, TYPE_CHECKING, cast
-from git.types import PathLike, TypeGuard, Literal
+from git.types import PathLike, Literal
if TYPE_CHECKING:
from git.repo import Repo
@@ -323,16 +323,18 @@ class Commit(base.Object, TraversableIterableObj, Diffable, Serializable):
:param proc: git-rev-list process instance - one sha per line
:return: iterator returning Commit objects"""
- def is_proc(inp) -> TypeGuard[Popen]:
- return hasattr(proc_or_stream, 'wait') and not hasattr(proc_or_stream, 'readline')
+ # def is_proc(inp) -> TypeGuard[Popen]:
+ # return hasattr(proc_or_stream, 'wait') and not hasattr(proc_or_stream, 'readline')
- def is_stream(inp) -> TypeGuard[IO]:
- return hasattr(proc_or_stream, 'readline')
+ # def is_stream(inp) -> TypeGuard[IO]:
+ # return hasattr(proc_or_stream, 'readline')
- if is_proc(proc_or_stream):
+ if hasattr(proc_or_stream, 'wait'):
+ proc_or_stream = cast(Popen, proc_or_stream)
if proc_or_stream.stdout is not None:
stream = proc_or_stream.stdout
- elif is_stream(proc_or_stream):
+ elif hasattr(proc_or_stream, 'readline'):
+ proc_or_stream = cast(IO, proc_or_stream)
stream = proc_or_stream
readline = stream.readline
@@ -351,7 +353,8 @@ class Commit(base.Object, TraversableIterableObj, Diffable, Serializable):
# END for each line in stream
# TODO: Review this - it seems process handling got a bit out of control
# due to many developers trying to fix the open file handles issue
- if is_proc(proc_or_stream):
+ if hasattr(proc_or_stream, 'wait'):
+ proc_or_stream = cast(Popen, proc_or_stream)
finalize_process(proc_or_stream)
@ classmethod
diff --git a/git/objects/submodule/base.py b/git/objects/submodule/base.py
index d5ba118f..29212167 100644
--- a/git/objects/submodule/base.py
+++ b/git/objects/submodule/base.py
@@ -965,13 +965,12 @@ class Submodule(IndexObject, TraversableIterableObj):
# now git config - need the config intact, otherwise we can't query
# information anymore
- writer: Union[GitConfigParser, SectionConstraint]
- with self.repo.config_writer() as writer:
- writer.remove_section(sm_section(self.name))
+ with self.repo.config_writer() as gcp_writer:
+ gcp_writer.remove_section(sm_section(self.name))
- with self.config_writer() as writer:
- writer.remove_section()
+ with self.config_writer() as sc_writer:
+ sc_writer.remove_section()
# END delete configuration
return self
@@ -1024,7 +1023,8 @@ class Submodule(IndexObject, TraversableIterableObj):
return self
@unbare_repo
- def config_writer(self, index: Union['IndexFile', None] = None, write: bool = True) -> SectionConstraint:
+ def config_writer(self, index: Union['IndexFile', None] = None, write: bool = True
+ ) -> SectionConstraint['SubmoduleConfigParser']:
""":return: a config writer instance allowing you to read and write the data
belonging to this submodule into the .gitmodules file.
@@ -1201,7 +1201,7 @@ class Submodule(IndexObject, TraversableIterableObj):
"""
return self._name
- def config_reader(self) -> SectionConstraint:
+ def config_reader(self) -> SectionConstraint[SubmoduleConfigParser]:
"""
:return: ConfigReader instance which allows you to qurey the configuration values
of this submodule, as provided by the .gitmodules file
diff --git a/git/objects/submodule/util.py b/git/objects/submodule/util.py
index a776af88..cc1cd60a 100644
--- a/git/objects/submodule/util.py
+++ b/git/objects/submodule/util.py
@@ -100,7 +100,7 @@ class SubmoduleConfigParser(GitConfigParser):
#} END interface
#{ Overridden Methods
- def write(self) -> None:
+ def write(self) -> None: # type: ignore[override]
rval: None = super(SubmoduleConfigParser, self).write()
self.flush_to_index()
return rval
diff --git a/git/objects/tree.py b/git/objects/tree.py
index dd1fe783..70f36af5 100644
--- a/git/objects/tree.py
+++ b/git/objects/tree.py
@@ -24,7 +24,7 @@ from .fun import (
from typing import (Any, Callable, Dict, Iterable, Iterator, List,
Tuple, Type, Union, cast, TYPE_CHECKING)
-from git.types import PathLike, TypeGuard, Literal
+from git.types import PathLike, Literal
if TYPE_CHECKING:
from git.repo import Repo
@@ -36,8 +36,8 @@ 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)
+# 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)
#--------------------------------------------------------
diff --git a/git/refs/reference.py b/git/refs/reference.py
index f584bb54..64662281 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, List, Match, Optional, Tuple, Type, TypeVar, Union, TYPE_CHECKING # NOQA
-from git.types import Commit_ish, PathLike, TBD, Literal, TypeGuard, _T # NOQA
+from git.types import Commit_ish, PathLike, TBD, Literal, _T # NOQA
if TYPE_CHECKING:
from git.repo import Repo
diff --git a/git/refs/symbolic.py b/git/refs/symbolic.py
index 426d40d4..0e9dad5c 100644
--- a/git/refs/symbolic.py
+++ b/git/refs/symbolic.py
@@ -24,7 +24,7 @@ from .log import RefLog
# typing ------------------------------------------------------------------
from typing import Any, Iterator, List, Match, Optional, Tuple, Type, TypeVar, Union, TYPE_CHECKING # NOQA
-from git.types import Commit_ish, PathLike, TBD, Literal, TypeGuard # NOQA
+from git.types import Commit_ish, PathLike, TBD, Literal # NOQA
if TYPE_CHECKING:
from git.repo import Repo
diff --git a/git/remote.py b/git/remote.py
index d903552f..11007cb6 100644
--- a/git/remote.py
+++ b/git/remote.py
@@ -23,6 +23,7 @@ from git.util import (
)
from .config import (
+ GitConfigParser,
SectionConstraint,
cp,
)
@@ -37,9 +38,9 @@ from .refs import (
# typing-------------------------------------------------------
from typing import (Any, Callable, Dict, Iterator, List, NoReturn, Optional, Sequence, # NOQA[TC002]
- TYPE_CHECKING, Type, Union, overload)
+ TYPE_CHECKING, Type, Union, cast, overload)
-from git.types import PathLike, Literal, TBD, TypeGuard, Commit_ish # NOQA[TC002]
+from git.types import PathLike, Literal, TBD, Commit_ish # NOQA[TC002]
if TYPE_CHECKING:
from git.repo.base import Repo
@@ -50,8 +51,8 @@ if TYPE_CHECKING:
flagKeyLiteral = Literal[' ', '!', '+', '-', '*', '=', 't', '?']
-def is_flagKeyLiteral(inp: str) -> TypeGuard[flagKeyLiteral]:
- return inp in [' ', '!', '+', '-', '=', '*', 't', '?']
+# def is_flagKeyLiteral(inp: str) -> TypeGuard[flagKeyLiteral]:
+# return inp in [' ', '!', '+', '-', '=', '*', 't', '?']
# -------------------------------------------------------------
@@ -342,8 +343,8 @@ class FetchInfo(IterableObj, object):
# parse lines
remote_local_ref_str: str
control_character, operation, local_remote_ref, remote_local_ref_str, note = match.groups()
- assert is_flagKeyLiteral(control_character), f"{control_character}"
-
+ # 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")
ref_type_name, fetch_note = fetch_note.split(' ', 1)
@@ -911,7 +912,7 @@ class Remote(LazyMixin, IterableObj):
return self._get_push_info(proc, progress)
@ property
- def config_reader(self) -> SectionConstraint:
+ def config_reader(self) -> SectionConstraint[GitConfigParser]:
"""
:return:
GitConfigParser compatible object able to read options for only our remote.
diff --git a/git/repo/base.py b/git/repo/base.py
index 64f32bd3..a57172c6 100644
--- a/git/repo/base.py
+++ b/git/repo/base.py
@@ -36,7 +36,7 @@ import gitdb
# typing ------------------------------------------------------
-from git.types import TBD, PathLike, Lit_config_levels, Commit_ish, Tree_ish, is_config_level
+from git.types import TBD, PathLike, Lit_config_levels, Commit_ish, Tree_ish
from typing import (Any, BinaryIO, Callable, Dict,
Iterator, List, Mapping, Optional, Sequence,
TextIO, Tuple, Type, Union,
@@ -482,7 +482,8 @@ class Repo(object):
raise ValueError("Invalid configuration level: %r" % config_level)
- def config_reader(self, config_level: Optional[Lit_config_levels] = None) -> GitConfigParser:
+ def config_reader(self, config_level: Optional[Lit_config_levels] = None
+ ) -> GitConfigParser:
"""
:return:
GitConfigParser allowing to read the full git configuration, but not to write it
@@ -498,12 +499,14 @@ class Repo(object):
unknown, instead the global path will be used."""
files = None
if config_level is None:
- files = [self._get_config_path(f) for f in self.config_level if is_config_level(f)]
+ files = [self._get_config_path(cast(Lit_config_levels, f))
+ for f in self.config_level if cast(Lit_config_levels, f)]
else:
files = [self._get_config_path(config_level)]
return GitConfigParser(files, read_only=True, repo=self)
- def config_writer(self, config_level: Lit_config_levels = "repository") -> GitConfigParser:
+ def config_writer(self, config_level: Lit_config_levels = "repository"
+ ) -> GitConfigParser:
"""
:return:
GitConfigParser allowing to write values of the specified configuration file level.
diff --git a/git/types.py b/git/types.py
index 53f0f1e4..ccaffef3 100644
--- a/git/types.py
+++ b/git/types.py
@@ -10,12 +10,13 @@ from typing import (Callable, Dict, NoReturn, Sequence, Tuple, Union, Any, Itera
if sys.version_info[:2] >= (3, 8):
from typing import Final, Literal, SupportsIndex, TypedDict, Protocol, runtime_checkable # noqa: F401
else:
- from typing_extensions import Final, Literal, SupportsIndex, TypedDict, Protocol, runtime_checkable # noqa: F401
+ from typing_extensions import (Final, Literal, SupportsIndex, # noqa: F401
+ TypedDict, Protocol, runtime_checkable) # noqa: F401
-if sys.version_info[:2] >= (3, 10):
- from typing import TypeGuard # noqa: F401
-else:
- from typing_extensions import TypeGuard # noqa: F401
+# if sys.version_info[:2] >= (3, 10):
+# from typing import TypeGuard # noqa: F401
+# else:
+# from typing_extensions import TypeGuard # noqa: F401
if sys.version_info[:2] < (3, 9):
@@ -41,9 +42,9 @@ Lit_commit_ish = Literal['commit', 'tag', 'blob', 'tree']
Lit_config_levels = Literal['system', 'global', 'user', 'repository']
-def is_config_level(inp: str) -> TypeGuard[Lit_config_levels]:
- # return inp in get_args(Lit_config_level) # only py >= 3.8
- return inp in ("system", "user", "global", "repository")
+# def is_config_level(inp: str) -> TypeGuard[Lit_config_levels]:
+# # return inp in get_args(Lit_config_level) # only py >= 3.8
+# return inp in ("system", "user", "global", "repository")
ConfigLevels_Tup = Tuple[Literal['system'], Literal['user'], Literal['global'], Literal['repository']]
diff --git a/requirements.txt b/requirements.txt
index 80d6b1b4..a20310fb 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,2 +1,2 @@
gitdb>=4.0.1,<5
-typing-extensions>=3.10.0.0;python_version<"3.10"
+typing-extensions>=3.7.4.3;python_version<"3.10"