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.
--- 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(
--- a/mercurial/posix.py Thu Jul 18 19:55:51 2024 -0400
+++ b/mercurial/posix.py Thu Jul 18 19:57:42 2024 -0400
@@ -707,6 +707,8 @@
class cachestat:
+ stat: os.stat_result
+
def __init__(self, path: bytes) -> None:
self.stat = os.stat(path)
--- a/mercurial/typelib.py Thu Jul 18 19:55:51 2024 -0400
+++ b/mercurial/typelib.py Thu Jul 18 19:57:42 2024 -0400
@@ -21,8 +21,21 @@
if TYPE_CHECKING:
from typing import (
BinaryIO,
+ Union,
+ )
+
+ from . import (
+ node,
+ posix,
+ windows,
)
BinaryIO_Proxy = BinaryIO
+ CacheStat = Union[posix.cachestat, windows.cachestat]
+ NodeConstants = node.sha1nodeconstants
else:
+ from typing import Any
+
BinaryIO_Proxy = object
+ CacheStat = Any
+ NodeConstants = Any
--- a/mercurial/windows.py Thu Jul 18 19:55:51 2024 -0400
+++ b/mercurial/windows.py Thu Jul 18 19:57:42 2024 -0400
@@ -675,8 +675,10 @@
class cachestat:
+ stat: Optional[os.stat_result]
+
def __init__(self, path: bytes) -> None:
- pass
+ self.stat = None
def cacheable(self) -> bool:
return False