1111
1212# typing ----------------------------------------------------------------------
1313
14- from typing import (List ,Sequence ,TYPE_CHECKING ,Tuple ,cast )
14+ from typing import (NamedTuple ,Sequence ,TYPE_CHECKING ,Tuple , Union ,cast )
1515
1616from git .types import PathLike
1717
@@ -59,7 +59,23 @@ def __call__(self, stage_blob: Blob) -> bool:
5959return False
6060
6161
62- class BaseIndexEntry (tuple ):
62+ class BaseIndexEntryHelper (NamedTuple ):
63+ """Typed namedtuple to provide named attribute access for BaseIndexEntry.
64+ Needed to allow overriding __new__ in child class to preserve backwards compat."""
65+ mode :int
66+ binsha :bytes
67+ flags :int
68+ path :PathLike
69+ ctime_bytes :bytes = pack (">LL" ,0 ,0 )
70+ mtime_bytes :bytes = pack (">LL" ,0 ,0 )
71+ dev :int = 0
72+ inode :int = 0
73+ uid :int = 0
74+ gid :int = 0
75+ size :int = 0
76+
77+
78+ class BaseIndexEntry (BaseIndexEntryHelper ):
6379
6480"""Small Brother of an index entry which can be created to describe changes
6581 done to the index in which case plenty of additional information is not required.
@@ -68,26 +84,22 @@ class BaseIndexEntry(tuple):
6884 expecting a BaseIndexEntry can also handle full IndexEntries even if they
6985 use numeric indices for performance reasons. """
7086
87+ def __new__ (cls ,inp_tuple :Union [Tuple [int ,bytes ,int ,PathLike ],
88+ Tuple [int ,bytes ,int ,PathLike ,bytes ,bytes ,int ,int ,int ,int ,int ]]
89+ )-> 'BaseIndexEntry' :
90+ """Override __new__ to allow construction from a tuple for backwards compatibility """
91+ return super ().__new__ (cls ,* inp_tuple )
92+
7193def __str__ (self )-> str :
7294return "%o %s %i\t %s" % (self .mode ,self .hexsha ,self .stage ,self .path )
7395
7496def __repr__ (self )-> str :
7597return "(%o, %s, %i, %s)" % (self .mode ,self .hexsha ,self .stage ,self .path )
7698
77- @property
78- def mode (self )-> int :
79- """ File Mode, compatible to stat module constants """
80- return self [0 ]
81-
82- @property
83- def binsha (self )-> bytes :
84- """binary sha of the blob """
85- return self [1 ]
86-
8799@property
88100def hexsha (self )-> str :
89101"""hex version of our sha"""
90- return b2a_hex (self [ 1 ] ).decode ('ascii' )
102+ return b2a_hex (self . binsha ).decode ('ascii' )
91103
92104@property
93105def stage (self )-> int :
@@ -100,17 +112,7 @@ def stage(self) -> int:
100112
101113 :note: For more information, see http://www.kernel.org/pub/software/scm/git/docs/git-read-tree.html
102114 """
103- return (self [2 ]& CE_STAGEMASK )>> CE_STAGESHIFT
104-
105- @property
106- def path (self )-> str :
107- """:return: our path relative to the repository working tree root"""
108- return self [3 ]
109-
110- @property
111- def flags (self )-> List [str ]:
112- """:return: flags stored with this entry"""
113- return self [2 ]
115+ return (self .flags & CE_STAGEMASK )>> CE_STAGESHIFT
114116
115117@classmethod
116118def from_blob (cls ,blob :Blob ,stage :int = 0 )-> 'BaseIndexEntry' :
@@ -136,40 +138,15 @@ def ctime(self) -> Tuple[int, int]:
136138 :return:
137139 Tuple(int_time_seconds_since_epoch, int_nano_seconds) of the
138140 file's creation time"""
139- return cast (Tuple [int ,int ],unpack (">LL" ,self [ 4 ] ))
141+ return cast (Tuple [int ,int ],unpack (">LL" ,self . ctime_bytes ))
140142
141143@property
142144def mtime (self )-> Tuple [int ,int ]:
143145"""See ctime property, but returns modification time """
144- return cast (Tuple [int ,int ],unpack (">LL" ,self [5 ]))
145-
146- @property
147- def dev (self )-> int :
148- """ Device ID """
149- return self [6 ]
150-
151- @property
152- def inode (self )-> int :
153- """ Inode ID """
154- return self [7 ]
155-
156- @property
157- def uid (self )-> int :
158- """ User ID """
159- return self [8 ]
160-
161- @property
162- def gid (self )-> int :
163- """ Group ID """
164- return self [9 ]
165-
166- @property
167- def size (self )-> int :
168- """:return: Uncompressed size of the blob """
169- return self [10 ]
146+ return cast (Tuple [int ,int ],unpack (">LL" ,self .mtime_bytes ))
170147
171148@classmethod
172- def from_base (cls ,base ) :
149+ def from_base (cls ,base : 'BaseIndexEntry' ) -> 'IndexEntry' :
173150"""
174151 :return:
175152 Minimal entry as created from the given BaseIndexEntry instance.