3939
4040# typing ---------------------------------------------------------------------------
4141
42- from typing import (Any , AnyStr , BinaryIO , Callable , Dict , IO , List , Mapping ,
42+ from typing import (Any , AnyStr , BinaryIO , Callable , Dict , IO , Iterator , List , Mapping ,
4343 Sequence , TYPE_CHECKING , TextIO , Tuple , Union , cast , overload )
4444
45- from git .types import PathLike , Literal , TBD
45+ from git .types import PathLike , Literal
4646
4747if TYPE_CHECKING :
4848 from git .repo .base import Repo
@@ -146,11 +146,11 @@ def dashify(string: str) -> str:
146146 return string .replace ('_' , '-' )
147147
148148
149- def slots_to_dict (self , exclude : Sequence [str ] = ()) -> Dict [str , Any ]:
149+ def slots_to_dict (self : object , exclude : Sequence [str ] = ()) -> Dict [str , Any ]:
150150 return {s : getattr (self , s ) for s in self .__slots__ if s not in exclude }
151151
152152
153- def dict_to_slots_and__excluded_are_none (self , d : Mapping [str , Any ], excluded : Sequence [str ] = ()) -> None :
153+ def dict_to_slots_and__excluded_are_none (self : object , d : Mapping [str , Any ], excluded : Sequence [str ] = ()) -> None :
154154 for k , v in d .items ():
155155 setattr (self , k , v )
156156 for k in excluded :
@@ -192,7 +192,7 @@ class Git(LazyMixin):
192192 def __getstate__ (self ) -> Dict [str , Any ]:
193193 return slots_to_dict (self , exclude = self ._excluded_ )
194194
195- def __setstate__ (self , d ) -> None :
195+ def __setstate__ (self , d : Dict [ str , Any ] ) -> None :
196196 dict_to_slots_and__excluded_are_none (self , d , excluded = self ._excluded_ )
197197
198198 # CONFIGURATION
@@ -434,10 +434,13 @@ def wait(self, stderr: Union[None, bytes] = b'') -> int:
434434 if self .proc is not None :
435435 status = self .proc .wait ()
436436
437- def read_all_from_possibly_closed_stream (stream ):
438- try :
439- return stderr + force_bytes (stream .read ())
440- except ValueError :
437+ def read_all_from_possibly_closed_stream (stream : Union [IO [bytes ], None ]) -> bytes :
438+ if stream :
439+ try :
440+ return stderr + force_bytes (stream .read ())
441+ except ValueError :
442+ return stderr or b''
443+ else :
441444 return stderr or b''
442445
443446 if status != 0 :
@@ -907,7 +910,7 @@ def _kill_process(pid: int) -> None:
907910 if self .GIT_PYTHON_TRACE == 'full' :
908911 cmdstr = " " .join (redacted_command )
909912
910- def as_text (stdout_value ) :
913+ def as_text (stdout_value : Union [ bytes , str ]) -> str :
911914 return not output_stream and safe_decode (stdout_value ) or '<OUTPUT_STREAM>'
912915 # end
913916
@@ -932,10 +935,10 @@ def as_text(stdout_value):
932935 else :
933936 return stdout_value
934937
935- def environment (self ):
938+ def environment (self ) -> Dict [ str , str ] :
936939 return self ._environment
937940
938- def update_environment (self , ** kwargs ) :
941+ def update_environment (self , ** kwargs : Any ) -> Dict [ str , Union [ str , None ]] :
939942 """
940943 Set environment variables for future git invocations. Return all changed
941944 values in a format that can be passed back into this function to revert
@@ -962,7 +965,7 @@ def update_environment(self, **kwargs):
962965 return old_env
963966
964967 @contextmanager
965- def custom_environment (self , ** kwargs ) :
968+ def custom_environment (self , ** kwargs : Any ) -> Iterator [ None ] :
966969 """
967970 A context manager around the above ``update_environment`` method to restore the
968971 environment back to its previous state after operation.
@@ -1043,6 +1046,13 @@ def _call_process(self, method: str, *args: None, **kwargs: None
10431046 ) -> str :
10441047 ... # if no args given, execute called with all defaults
10451048
1049+ @overload
1050+ def _call_process (self , method : str ,
1051+ istream : int ,
1052+ as_process : Literal [True ],
1053+ * args : Any , ** kwargs : Any
1054+ ) -> 'Git.AutoInterrupt' : ...
1055+
10461056 @overload
10471057 def _call_process (self , method : str , * args : Any , ** kwargs : Any
10481058 ) -> Union [str , bytes , Tuple [int , Union [str , bytes ], str ], 'Git.AutoInterrupt' ]:
@@ -1156,7 +1166,7 @@ def _prepare_ref(self, ref: AnyStr) -> bytes:
11561166 return refstr .encode (defenc )
11571167
11581168 def _get_persistent_cmd (self , attr_name : str , cmd_name : str , * args : Any , ** kwargs : Any
1159- ) -> Union [ 'Git.AutoInterrupt' , TBD ] :
1169+ ) -> 'Git.AutoInterrupt' :
11601170 cur_val = getattr (self , attr_name )
11611171 if cur_val is not None :
11621172 return cur_val
@@ -1166,12 +1176,16 @@ def _get_persistent_cmd(self, attr_name: str, cmd_name: str, *args: Any, **kwarg
11661176
11671177 cmd = self ._call_process (cmd_name , * args , ** options )
11681178 setattr (self , attr_name , cmd )
1179+ cmd = cast ('Git.AutoInterrupt' , cmd )
11691180 return cmd
11701181
1171- def __get_object_header (self , cmd , ref : AnyStr ) -> Tuple [str , str , int ]:
1172- cmd .stdin .write (self ._prepare_ref (ref ))
1173- cmd .stdin .flush ()
1174- return self ._parse_object_header (cmd .stdout .readline ())
1182+ def __get_object_header (self , cmd : 'Git.AutoInterrupt' , ref : AnyStr ) -> Tuple [str , str , int ]:
1183+ if cmd .stdin and cmd .stdout :
1184+ cmd .stdin .write (self ._prepare_ref (ref ))
1185+ cmd .stdin .flush ()
1186+ return self ._parse_object_header (cmd .stdout .readline ())
1187+ else :
1188+ raise ValueError ("cmd stdin was empty" )
11751189
11761190 def get_object_header (self , ref : str ) -> Tuple [str , str , int ]:
11771191 """ Use this method to quickly examine the type and size of the object behind
@@ -1200,7 +1214,8 @@ def stream_object_data(self, ref: str) -> Tuple[str, str, int, 'Git.CatFileConte
12001214 :note: This method is not threadsafe, you need one independent Command instance per thread to be safe !"""
12011215 cmd = self ._get_persistent_cmd ("cat_file_all" , "cat_file" , batch = True )
12021216 hexsha , typename , size = self .__get_object_header (cmd , ref )
1203- return (hexsha , typename , size , self .CatFileContentStream (size , cmd .stdout ))
1217+ cmd_stdout = cmd .stdout if cmd .stdout is not None else io .BytesIO ()
1218+ return (hexsha , typename , size , self .CatFileContentStream (size , cmd_stdout ))
12041219
12051220 def clear_cache (self ) -> 'Git' :
12061221 """Clear all kinds of internal caches to release resources.
0 commit comments