88import enum
99import logging
1010import os
11+ from collections .abc import Iterator
1112from contextlib import suppress
13+ from typing import TypedDict
1214
1315from gitfourchette import colors
1416from gitfourchette import pycompat # noqa: F401 - StrEnum for Python 3.10
@@ -239,9 +241,15 @@ def isGitSandboxed(self):
239241class History (PrefsFile ):
240242 _filename = "history.json"
241243
242- repos : dict = dataclasses .field (default_factory = dict )
243- cloneHistory : list = dataclasses .field (default_factory = list )
244- fileDialogPaths : dict = dataclasses .field (default_factory = dict )
244+ class JsonRepo (TypedDict , total = False ):
245+ seq : int
246+ length : int
247+ nickname : str
248+ superproject : str
249+
250+ repos : dict [str , JsonRepo ] = dataclasses .field (default_factory = dict )
251+ cloneHistory : list [str ] = dataclasses .field (default_factory = list )
252+ fileDialogPaths : dict [str , str ] = dataclasses .field (default_factory = dict )
245253 startups : int = 0
246254
247255 _maxSeq = - 1
@@ -252,12 +260,12 @@ def addRepo(self, path: str):
252260 repo ['seq' ] = self .drawSequenceNumber ()
253261 return repo
254262
255- def getRepo (self , path : str ) -> dict :
263+ def getRepo (self , path : str ) -> JsonRepo :
256264 path = os .path .normpath (path )
257265 try :
258266 repo = self .repos [path ]
259267 except KeyError :
260- repo = {}
268+ repo : History . JsonRepo = {}
261269 self .repos [path ] = repo
262270 return repo
263271
@@ -274,7 +282,7 @@ def setRepoNickname(self, path: str, nickname: str):
274282 else :
275283 repo .pop ('nickname' , None )
276284
277- def getRepoNumCommits (self , path : str ):
285+ def getRepoNumCommits (self , path : str ) -> int :
278286 repo = self .getRepo (path )
279287 return repo .get ('length' , 0 )
280288
@@ -285,7 +293,7 @@ def setRepoNumCommits(self, path: str, commitCount: int):
285293 else :
286294 repo .pop ('length' , None )
287295
288- def getRepoSuperproject (self , path : str ):
296+ def getRepoSuperproject (self , path : str ) -> str :
289297 repo = self .getRepo (path )
290298 return repo .get ('superproject' , "" )
291299
@@ -296,7 +304,7 @@ def setRepoSuperproject(self, path: str, superprojectPath: str):
296304 else :
297305 repo .pop ('superproject' , None )
298306
299- def getRepoTabName (self , path : str ):
307+ def getRepoTabName (self , path : str ) -> str :
300308 name = self .getRepoNickname (path )
301309
302310 seen = {path }
@@ -321,7 +329,7 @@ def clearRepoHistory(self):
321329 self .repos .clear ()
322330 self .invalidateSequenceNumber ()
323331
324- def getRecentRepoPaths (self , n : int , newestFirst = True ):
332+ def getRecentRepoPaths (self , n : int , newestFirst = True ) -> Iterator [ str ] :
325333 sortedPaths = (path for path , _ in
326334 sorted (self .repos .items (), key = lambda i : i [1 ].get ('seq' , - 1 ), reverse = newestFirst ))
327335
@@ -365,10 +373,10 @@ def invalidateSequenceNumber(self):
365373class Session (PrefsFile ):
366374 _filename = "session.json"
367375
368- tabs : list = dataclasses .field (default_factory = list )
369- activeTabIndex : int = - 1
370- windowGeometry : bytes = b""
371- splitterSizes : dict = dataclasses .field (default_factory = dict )
376+ tabs : list [ str ] = dataclasses .field (default_factory = list )
377+ activeTabIndex : int = - 1
378+ windowGeometry : bytes = b""
379+ splitterSizes : dict [ str , list [ int ]] = dataclasses .field (default_factory = dict )
372380
373381
374382# Initialize default prefs and history.
0 commit comments