Skip to content

Commit fe594eb

Browse files
committed
Add T_Tre_cache TypeVar
1 parent affee35 commit fe594eb

File tree

3 files changed

+22
-18
lines changed

3 files changed

+22
-18
lines changed

‎git/objects/tree.py

+18-14
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020

2121
# typing -------------------------------------------------
2222

23-
from typing import Callable, Dict, Iterable, Iterator, List, Tuple, Type, Union, cast, TYPE_CHECKING
23+
from typing import Callable, Dict, Generic, Iterable, Iterator, List, Tuple, Type, TypeVar, Union, cast, TYPE_CHECKING
2424

2525
from git.types import PathLike
2626

@@ -31,13 +31,16 @@
3131
#--------------------------------------------------------
3232

3333

34-
cmp: Callable[[int, int], int] = lambda a, b: (a > b) - (a < b)
34+
cmp: Callable[[str, str], int] = lambda a, b: (a > b) - (a < b)
3535

3636
__all__ = ("TreeModifier", "Tree")
3737

38+
T_Tree_cache = TypeVar('T_Tree_cache', bound=Union[Tuple[bytes, int, str]])
3839

39-
def git_cmp(t1: 'Tree', t2: 'Tree') -> int:
40+
41+
def git_cmp(t1: T_Tree_cache, t2: T_Tree_cache) -> int:
4042
a, b = t1[2], t2[2]
43+
assert isinstance(a, str) and isinstance(b, str) # Need as mypy 9.0 cannot unpack TypeVar properly
4144
len_a, len_b = len(a), len(b)
4245
min_len = min(len_a, len_b)
4346
min_cmp = cmp(a[:min_len], b[:min_len])
@@ -48,7 +51,8 @@ def git_cmp(t1: 'Tree', t2: 'Tree') -> int:
4851
return len_a - len_b
4952

5053

51-
def merge_sort(a: List[int], cmp: Callable[[int, int], int]) -> None:
54+
def merge_sort(a: List[T_Tree_cache],
55+
cmp: Callable[[T_Tree_cache, T_Tree_cache], int]) -> None:
5256
if len(a) < 2:
5357
return None
5458

@@ -83,18 +87,18 @@ def merge_sort(a: List[int], cmp: Callable[[int, int], int]) -> None:
8387
k = k + 1
8488

8589

86-
class TreeModifier(object):
90+
class TreeModifier(Generic[T_Tree_cache], object):
8791

8892
"""A utility class providing methods to alter the underlying cache in a list-like fashion.
8993
9094
Once all adjustments are complete, the _cache, which really is a reference to
9195
the cache of a tree, will be sorted. Assuring it will be in a serializable state"""
9296
__slots__ = '_cache'
9397

94-
def __init__(self, cache):
98+
def __init__(self, cache: List[T_Tree_cache]) -> None:
9599
self._cache = cache
96100

97-
def _index_by_name(self, name):
101+
def _index_by_name(self, name: str) -> int:
98102
""":return: index of an item with name, or -1 if not found"""
99103
for i, t in enumerate(self._cache):
100104
if t[2] == name:
@@ -104,7 +108,7 @@ def _index_by_name(self, name):
104108
return -1
105109

106110
#{ Interface
107-
def set_done(self):
111+
def set_done(self) -> 'TreeModifier':
108112
"""Call this method once you are done modifying the tree information.
109113
It may be called several times, but be aware that each call will cause
110114
a sort operation
@@ -114,7 +118,7 @@ def set_done(self):
114118
#} END interface
115119

116120
#{ Mutators
117-
def add(self, sha, mode, name, force=False):
121+
def add(self, sha: bytes, mode: int, name: str, force: bool = False) -> 'TreeModifier':
118122
"""Add the given item to the tree. If an item with the given name already
119123
exists, nothing will be done, but a ValueError will be raised if the
120124
sha and mode of the existing item do not match the one you add, unless
@@ -132,7 +136,7 @@ def add(self, sha, mode, name, force=False):
132136

133137
sha = to_bin_sha(sha)
134138
index = self._index_by_name(name)
135-
item = (sha, mode, name)
139+
item: T_Tree_cache = (sha, mode, name) # type: ignore ## use Typeguard from typing-extensions 3.10.0
136140
if index == -1:
137141
self._cache.append(item)
138142
else:
@@ -195,7 +199,7 @@ class Tree(IndexObject, diff.Diffable, util.Traversable, util.Serializable):
195199
def __init__(self, repo: 'Repo', binsha: bytes, mode: int = tree_id << 12, path: Union[PathLike, None] = None):
196200
super(Tree, self).__init__(repo, binsha, mode, path)
197201

198-
@classmethod
202+
@ classmethod
199203
def _get_intermediate_items(cls, index_object: 'Tree', # type: ignore
200204
) -> Union[Tuple['Tree', ...], Tuple[()]]:
201205
if index_object.type == "tree":
@@ -261,17 +265,17 @@ def __truediv__(self, file: str) -> Union['Tree', Blob, Submodule]:
261265
"""For PY3 only"""
262266
return self.join(file)
263267

264-
@property
268+
@ property
265269
def trees(self) -> List['Tree']:
266270
""":return: list(Tree, ...) list of trees directly below this tree"""
267271
return [i for i in self if i.type == "tree"]
268272

269-
@property
273+
@ property
270274
def blobs(self) -> List['Blob']:
271275
""":return: list(Blob, ...) list of blobs directly below this tree"""
272276
return [i for i in self if i.type == "blob"]
273277

274-
@property
278+
@ property
275279
def cache(self) -> TreeModifier:
276280
"""
277281
:return: An object allowing to modify the internal cache. This can be used

‎git/types.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,4 @@ class Total_TD(TypedDict):
3939

4040
class HSH_TD(TypedDict):
4141
total: Total_TD
42-
files: Dict[str, Files_TD]
42+
files: Dict[PathLike, Files_TD]

‎git/util.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -672,7 +672,7 @@ def _from_string(cls, string: str) -> 'Actor':
672672

673673
@classmethod
674674
def _main_actor(cls, env_name: str, env_email: str,
675-
config_reader: Union[None, GitConfigParser, SectionConstraint] = None) -> 'Actor':
675+
config_reader: Union[None, 'GitConfigParser', 'SectionConstraint'] = None) -> 'Actor':
676676
actor = Actor('', '')
677677
user_id = None # We use this to avoid multiple calls to getpass.getuser()
678678

@@ -701,7 +701,7 @@ def default_name() -> str:
701701
return actor
702702

703703
@classmethod
704-
def committer(cls, config_reader: Union[None, GitConfigParser, SectionConstraint] = None) -> 'Actor':
704+
def committer(cls, config_reader: Union[None, 'GitConfigParser', 'SectionConstraint'] = None) -> 'Actor':
705705
"""
706706
:return: Actor instance corresponding to the configured committer. It behaves
707707
similar to the git implementation, such that the environment will override
@@ -748,7 +748,7 @@ class Stats(object):
748748

749749
from git.types import Total_TD, Files_TD
750750

751-
def __init__(self, total: Total_TD, files: Dict[str, Files_TD]):
751+
def __init__(self, total: Total_TD, files: Dict[PathLike, Files_TD]):
752752
self.total = total
753753
self.files = files
754754

0 commit comments

Comments
 (0)