39
39
40
40
# typing ---------------------------------------------------------------------------
41
41
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 ,
43
43
Sequence , TYPE_CHECKING , TextIO , Tuple , Union , cast , overload )
44
44
45
- from git .types import PathLike , Literal , TBD
45
+ from git .types import PathLike , Literal
46
46
47
47
if TYPE_CHECKING :
48
48
from git .repo .base import Repo
@@ -146,11 +146,11 @@ def dashify(string: str) -> str:
146
146
return string .replace ('_' , '-' )
147
147
148
148
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 ]:
150
150
return {s : getattr (self , s ) for s in self .__slots__ if s not in exclude }
151
151
152
152
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 :
154
154
for k , v in d .items ():
155
155
setattr (self , k , v )
156
156
for k in excluded :
@@ -192,7 +192,7 @@ class Git(LazyMixin):
192
192
def __getstate__ (self ) -> Dict [str , Any ]:
193
193
return slots_to_dict (self , exclude = self ._excluded_ )
194
194
195
- def __setstate__ (self , d ) -> None :
195
+ def __setstate__ (self , d : Dict [ str , Any ] ) -> None :
196
196
dict_to_slots_and__excluded_are_none (self , d , excluded = self ._excluded_ )
197
197
198
198
# CONFIGURATION
@@ -434,10 +434,13 @@ def wait(self, stderr: Union[None, bytes] = b'') -> int:
434
434
if self .proc is not None :
435
435
status = self .proc .wait ()
436
436
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 :
441
444
return stderr or b''
442
445
443
446
if status != 0 :
@@ -907,7 +910,7 @@ def _kill_process(pid: int) -> None:
907
910
if self .GIT_PYTHON_TRACE == 'full' :
908
911
cmdstr = " " .join (redacted_command )
909
912
910
- def as_text (stdout_value ) :
913
+ def as_text (stdout_value : Union [ bytes , str ]) -> str :
911
914
return not output_stream and safe_decode (stdout_value ) or '<OUTPUT_STREAM>'
912
915
# end
913
916
@@ -932,10 +935,10 @@ def as_text(stdout_value):
932
935
else :
933
936
return stdout_value
934
937
935
- def environment (self ):
938
+ def environment (self ) -> Dict [ str , str ] :
936
939
return self ._environment
937
940
938
- def update_environment (self , ** kwargs ) :
941
+ def update_environment (self , ** kwargs : Any ) -> Dict [ str , Union [ str , None ]] :
939
942
"""
940
943
Set environment variables for future git invocations. Return all changed
941
944
values in a format that can be passed back into this function to revert
@@ -962,7 +965,7 @@ def update_environment(self, **kwargs):
962
965
return old_env
963
966
964
967
@contextmanager
965
- def custom_environment (self , ** kwargs ) :
968
+ def custom_environment (self , ** kwargs : Any ) -> Iterator [ None ] :
966
969
"""
967
970
A context manager around the above ``update_environment`` method to restore the
968
971
environment back to its previous state after operation.
@@ -1043,6 +1046,13 @@ def _call_process(self, method: str, *args: None, **kwargs: None
1043
1046
) -> str :
1044
1047
... # if no args given, execute called with all defaults
1045
1048
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
+
1046
1056
@overload
1047
1057
def _call_process (self , method : str , * args : Any , ** kwargs : Any
1048
1058
) -> Union [str , bytes , Tuple [int , Union [str , bytes ], str ], 'Git.AutoInterrupt' ]:
@@ -1156,7 +1166,7 @@ def _prepare_ref(self, ref: AnyStr) -> bytes:
1156
1166
return refstr .encode (defenc )
1157
1167
1158
1168
def _get_persistent_cmd (self , attr_name : str , cmd_name : str , * args : Any , ** kwargs : Any
1159
- ) -> Union [ 'Git.AutoInterrupt' , TBD ] :
1169
+ ) -> 'Git.AutoInterrupt' :
1160
1170
cur_val = getattr (self , attr_name )
1161
1171
if cur_val is not None :
1162
1172
return cur_val
@@ -1166,12 +1176,16 @@ def _get_persistent_cmd(self, attr_name: str, cmd_name: str, *args: Any, **kwarg
1166
1176
1167
1177
cmd = self ._call_process (cmd_name , * args , ** options )
1168
1178
setattr (self , attr_name , cmd )
1179
+ cmd = cast ('Git.AutoInterrupt' , cmd )
1169
1180
return cmd
1170
1181
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" )
1175
1189
1176
1190
def get_object_header (self , ref : str ) -> Tuple [str , str , int ]:
1177
1191
""" 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
1200
1214
:note: This method is not threadsafe, you need one independent Command instance per thread to be safe !"""
1201
1215
cmd = self ._get_persistent_cmd ("cat_file_all" , "cat_file" , batch = True )
1202
1216
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 ))
1204
1219
1205
1220
def clear_cache (self ) -> 'Git' :
1206
1221
"""Clear all kinds of internal caches to release resources.
0 commit comments