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
2525from git .types import PathLike
2626
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 :
4042a ,b = t1 [2 ],t2 [2 ]
43+ assert isinstance (a ,str )and isinstance (b ,str )# Need as mypy 9.0 cannot unpack TypeVar properly
4144len_a ,len_b = len (a ),len (b )
4245min_len = min (len_a ,len_b )
4346min_cmp = cmp (a [:min_len ],b [:min_len ])
@@ -48,7 +51,8 @@ def git_cmp(t1: 'Tree', t2: 'Tree') -> int:
4851return 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 :
5256if len (a )< 2 :
5357return None
5458
@@ -83,18 +87,18 @@ def merge_sort(a: List[int], cmp: Callable[[int, int], int]) -> None:
8387k = 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 :
9599self ._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"""
99103for i ,t in enumerate (self ._cache ):
100104if t [2 ]== name :
@@ -104,7 +108,7 @@ def _index_by_name(self, name):
104108return - 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
133137sha = to_bin_sha (sha )
134138index = 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
136140if index == - 1 :
137141self ._cache .append (item )
138142else :
@@ -195,7 +199,7 @@ class Tree(IndexObject, diff.Diffable, util.Traversable, util.Serializable):
195199def __init__ (self ,repo :'Repo' ,binsha :bytes ,mode :int = tree_id << 12 ,path :Union [PathLike ,None ]= None ):
196200super (Tree ,self ).__init__ (repo ,binsha ,mode ,path )
197201
198- @classmethod
202+ @classmethod
199203def _get_intermediate_items (cls ,index_object :'Tree' ,# type: ignore
200204 )-> Union [Tuple ['Tree' , ...],Tuple [()]]:
201205if index_object .type == "tree" :
@@ -261,17 +265,17 @@ def __truediv__(self, file: str) -> Union['Tree', Blob, Submodule]:
261265"""For PY3 only"""
262266return self .join (file )
263267
264- @property
268+ @property
265269def trees (self )-> List ['Tree' ]:
266270""":return: list(Tree, ...) list of trees directly below this tree"""
267271return [i for i in self if i .type == "tree" ]
268272
269- @property
273+ @property
270274def blobs (self )-> List ['Blob' ]:
271275""":return: list(Blob, ...) list of blobs directly below this tree"""
272276return [i for i in self if i .type == "blob" ]
273277
274- @property
278+ @property
275279def cache (self )-> TreeModifier :
276280"""
277281 :return: An object allowing to modify the internal cache. This can be used