77import logging
88import os
99import re
10+ from dataclasses import dataclass
1011import shlex
1112import warnings
1213from gitdb .db .loose import LooseObjectDB
4142from git .types import TBD , PathLike , Lit_config_levels , Commit_ish , Tree_ish , assert_never
4243from typing import (Any , BinaryIO , Callable , Dict ,
4344 Iterator , List , Mapping , Optional , Sequence ,
44- TextIO , Tuple , Type , Union ,
45+ TextIO , Tuple , Type , TypedDict , Union ,
4546 NamedTuple , cast , TYPE_CHECKING )
4647
47- from git .types import ConfigLevels_Tup , TypedDict
48+ from git .types import ConfigLevels_Tup
4849
4950if TYPE_CHECKING :
5051 from git .util import IterableList
@@ -889,7 +890,7 @@ def blame(self, rev: Union[str, HEAD], file: str, incremental: bool = False, **k
889890 commits : Dict [str , Commit ] = {}
890891 blames : List [List [Commit | List [str | bytes ] | None ]] = []
891892
892- class InfoTD (TypedDict , total = False ):
893+ class InfoTC (TypedDict , total = False ):
893894 sha : str
894895 id : str
895896 filename : str
@@ -901,15 +902,29 @@ class InfoTD(TypedDict, total=False):
901902 committer_email : str
902903 committer_date : int
903904
904- info : InfoTD = {}
905+ @dataclass
906+ class InfoDC (Dict [str , Union [str , int ]]):
907+ sha : str = ''
908+ id : str = ''
909+ filename : str = ''
910+ summary : str = ''
911+ author : str = ''
912+ author_email : str = ''
913+ author_date : int = 0
914+ committer : str = ''
915+ committer_email : str = ''
916+ committer_date : int = 0
917+
918+ # info: InfoTD = {}
919+ info = InfoDC ()
905920
906921 keepends = True
907922 for line_bytes in data .splitlines (keepends ):
908923 try :
909924 line_str = line_bytes .rstrip ().decode (defenc )
910925 except UnicodeDecodeError :
911926 firstpart = ''
912- parts = []
927+ parts = ['' ]
913928 is_binary = True
914929 else :
915930 # As we don't have an idea when the binary data ends, as it could contain multiple newlines
@@ -928,10 +943,10 @@ class InfoTD(TypedDict, total=False):
928943 # another line of blame with the same data
929944 digits = parts [- 1 ].split (" " )
930945 if len (digits ) == 3 :
931- info = { 'id' : firstpart }
946+ info . id = firstpart
932947 blames .append ([None , []])
933- elif info [ 'id' ] != firstpart :
934- info = { 'id' : firstpart }
948+ elif info . id != firstpart :
949+ info . id = firstpart
935950 blames .append ([commits .get (firstpart ), []])
936951 # END blame data initialization
937952 else :
@@ -947,20 +962,12 @@ class InfoTD(TypedDict, total=False):
947962 # committer-time 1192271832
948963 # committer-tz -0700 - IGNORED BY US
949964 role = m .group (0 )
950- if role == 'author' :
951- if firstpart .endswith ('-mail' ):
952- info ["author_email" ] = parts [- 1 ]
953- elif firstpart .endswith ('-time' ):
954- info ["author_date" ] = int (parts [- 1 ])
955- elif role == firstpart :
956- info ["author" ] = parts [- 1 ]
957- elif role == 'committer' :
958- if firstpart .endswith ('-mail' ):
959- info ["committer_email" ] = parts [- 1 ]
960- elif firstpart .endswith ('-time' ):
961- info ["committer_date" ] = int (parts [- 1 ])
962- elif role == firstpart :
963- info ["committer" ] = parts [- 1 ]
965+ if firstpart .endswith ('-mail' ):
966+ info [f"{ role } _email" ] = parts [- 1 ]
967+ elif firstpart .endswith ('-time' ):
968+ info [f"{ role } _date" ] = int (parts [- 1 ])
969+ elif role == firstpart :
970+ info [role ] = parts [- 1 ]
964971 # END distinguish mail,time,name
965972 else :
966973 # handle
@@ -973,33 +980,33 @@ class InfoTD(TypedDict, total=False):
973980 info ['summary' ] = parts [- 1 ]
974981 elif firstpart == '' :
975982 if info :
976- sha = info [ 'id' ]
983+ sha = info . id
977984 c = commits .get (sha )
978985 if c is None :
979986 c = Commit (self , hex_to_bin (sha ),
980- author = Actor ._from_string (info [ ' author' ] + ' ' + info [ ' author_email' ] ),
981- authored_date = info [ ' author_date' ] ,
987+ author = Actor ._from_string (info . author + ' ' + info . author_email ),
988+ authored_date = info . author_date ,
982989 committer = Actor ._from_string (
983- info [ ' committer' ] + ' ' + info [ ' committer_email' ] ),
984- committed_date = info [ ' committer_date' ] )
990+ info . committer + ' ' + info . committer_email ),
991+ committed_date = info . committer_date )
985992 commits [sha ] = c
986993 blames [- 1 ][0 ] = c
987994 # END if commit objects needs initial creation
988-
989995 if blames [- 1 ][1 ] is not None :
990996 if not is_binary :
991997 if line_str and line_str [0 ] == '\t ' :
992998 line_str = line_str [1 :]
999+
9931000 blames [- 1 ][1 ].append (line_str )
9941001 else :
995- blames [- 1 ][1 ].append (line_bytes )
9961002 # NOTE: We are actually parsing lines out of binary data, which can lead to the
9971003 # binary being split up along the newline separator. We will append this to the
9981004 # blame we are currently looking at, even though it should be concatenated with
9991005 # the last line we have seen.
1000- info = { 'id' : sha }
1006+ blames [ - 1 ][ 1 ]. append ( line_bytes )
10011007 # end handle line contents
10021008
1009+ info .id = sha
10031010 # END if we collected commit info
10041011 # END distinguish filename,summary,rest
10051012 # END distinguish author|committer vs filename,summary,rest
0 commit comments