diff mercurial/dirstatemap.py @ 51716:f3b34386d3e0

typing: add type hints to `mercurial.dirstatemap` Somewhere since 10db46e128d4, pytype stopped being able to infer the type of the `identity` field. Fill in some obvious other hints along the way. These hints caused pytype to flag a missing attribute: File "/mnt/c/Users/Matt/hg/mercurial/dirstatemap.py", line 714, in _v1_map: No attribute 'stat' on mercurial.windows.cachestat [attribute-error] In Union[Any, mercurial.posix.cachestat, mercurial.windows.cachestat] File "/mnt/c/Users/Matt/hg/mercurial/dirstatemap.py", line 715, in _v1_map: No attribute 'stat' on mercurial.windows.cachestat [attribute-error] In Union[Any, mercurial.posix.cachestat, mercurial.windows.cachestat] In practice, the `identity` field is NOT replaced with None if it isn't cacheable, so it's probably safer to just add the field and set it to None, since that check is already in place on line 715.
author Matt Harbison <matt_harbison@yahoo.com>
date Thu, 18 Jul 2024 19:57:42 -0400
parents ca7bde5dbafb
children f4733654f144
line wrap: on
line diff
--- a/mercurial/dirstatemap.py	Thu Jul 18 19:55:51 2024 -0400
+++ b/mercurial/dirstatemap.py	Thu Jul 18 19:57:42 2024 -0400
@@ -4,6 +4,11 @@
 # GNU General Public License version 2 or any later version.
 
 
+from typing import (
+    Optional,
+    TYPE_CHECKING,
+)
+
 from .i18n import _
 
 from . import (
@@ -12,6 +17,7 @@
     policy,
     testing,
     txnutil,
+    typelib,
     util,
 )
 
@@ -20,6 +26,11 @@
     v2,
 )
 
+if TYPE_CHECKING:
+    from . import (
+        ui as uimod,
+    )
+
 parsers = policy.importmod('parsers')
 rustmod = policy.importrust('dirstate')
 
@@ -46,12 +57,31 @@
     class, with and without Rust extensions enabled.
     """
 
+    _use_dirstate_v2: bool
+    _nodeconstants: typelib.NodeConstants
+    _ui: "uimod.ui"
+    _root: bytes
+    _filename: bytes
+    _nodelen: int
+    _dirtyparents: bool
+    _docket: Optional["docketmod.DirstateDocket"]
+    _write_mode: int
+    _pendingmode: Optional[bool]
+    identity: Optional[typelib.CacheStat]
+
     # please pytype
 
     _map = None
     copymap = None
 
-    def __init__(self, ui, opener, root, nodeconstants, use_dirstate_v2):
+    def __init__(
+        self,
+        ui: "uimod.ui",
+        opener,
+        root: bytes,
+        nodeconstants: typelib.NodeConstants,
+        use_dirstate_v2: bool,
+    ) -> None:
         self._use_dirstate_v2 = use_dirstate_v2
         self._nodeconstants = nodeconstants
         self._ui = ui
@@ -76,16 +106,16 @@
         # for consistent view between _pl() and _read() invocations
         self._pendingmode = None
 
-    def _set_identity(self):
+    def _set_identity(self) -> None:
         self.identity = self._get_current_identity()
 
-    def _get_current_identity(self):
+    def _get_current_identity(self) -> Optional[typelib.CacheStat]:
         try:
             return util.cachestat(self._opener.join(self._filename))
         except FileNotFoundError:
             return None
 
-    def may_need_refresh(self):
+    def may_need_refresh(self) -> bool:
         if 'identity' not in vars(self):
             # no existing identity, we need a refresh
             return True
@@ -104,7 +134,7 @@
             return True
         return current_identity != self.identity
 
-    def preload(self):
+    def preload(self) -> None:
         """Loads the underlying data, if it's not already loaded"""
         self._map
 
@@ -135,7 +165,7 @@
         self._pendingmode = mode
         return fp
 
-    def _readdirstatefile(self, size=-1):
+    def _readdirstatefile(self, size: int = -1) -> bytes:
         try:
             with self._opendirstatefile() as fp:
                 return fp.read(size)
@@ -144,7 +174,7 @@
             return b''
 
     @property
-    def docket(self):
+    def docket(self) -> "docketmod.DirstateDocket":
         if not self._docket:
             if not self._use_dirstate_v2:
                 raise error.ProgrammingError(