##// END OF EJS Templates
typing: align the signatures of `repository.imanifestdict` overrides...
Matt Harbison -
r53389:48cdbd4d default
parent child Browse files
Show More
@@ -1,5 +1,13
1 from __future__ import annotations
1 from __future__ import annotations
2
2
3 import typing
4
5 from typing import (
6 Any,
7 Iterator,
8 Set,
9 )
10
3 from mercurial import (
11 from mercurial import (
4 match as matchmod,
12 match as matchmod,
5 pathutil,
13 pathutil,
@@ -12,6 +20,10 from mercurial.interfaces import (
12 )
20 )
13 from . import gitutil
21 from . import gitutil
14
22
23 if typing.TYPE_CHECKING:
24 from typing import (
25 ByteString, # TODO: change to Buffer for 3.14
26 )
15
27
16 pygit2 = gitutil.get_pygit2()
28 pygit2 = gitutil.get_pygit2()
17
29
@@ -71,16 +83,16 class gittreemanifest:
71 raise ValueError('unsupported mode %s' % oct(ent.filemode))
83 raise ValueError('unsupported mode %s' % oct(ent.filemode))
72 return ent.id.raw, flags
84 return ent.id.raw, flags
73
85
74 def __getitem__(self, path):
86 def __getitem__(self, path: bytes) -> bytes:
75 return self._resolve_entry(path)[0]
87 return self._resolve_entry(path)[0]
76
88
77 def find(self, path):
89 def find(self, path: bytes) -> tuple[bytes, bytes]:
78 return self._resolve_entry(path)
90 return self._resolve_entry(path)
79
91
80 def __len__(self):
92 def __len__(self) -> int:
81 return len(list(self.walk(matchmod.always())))
93 return len(list(self.walk(matchmod.always())))
82
94
83 def __nonzero__(self):
95 def __nonzero__(self) -> bool:
84 try:
96 try:
85 next(iter(self))
97 next(iter(self))
86 return True
98 return True
@@ -89,30 +101,30 class gittreemanifest:
89
101
90 __bool__ = __nonzero__
102 __bool__ = __nonzero__
91
103
92 def __contains__(self, path):
104 def __contains__(self, path: bytes) -> bool:
93 try:
105 try:
94 self._resolve_entry(path)
106 self._resolve_entry(path)
95 return True
107 return True
96 except KeyError:
108 except KeyError:
97 return False
109 return False
98
110
99 def iterkeys(self):
111 def iterkeys(self) -> Iterator[bytes]:
100 return self.walk(matchmod.always())
112 return self.walk(matchmod.always())
101
113
102 def keys(self):
114 def keys(self) -> list[bytes]:
103 return list(self.iterkeys())
115 return list(self.iterkeys())
104
116
105 def __iter__(self):
117 def __iter__(self) -> Iterator[bytes]:
106 return self.iterkeys()
118 return self.iterkeys()
107
119
108 def __setitem__(self, path, node):
120 def __setitem__(self, path: bytes, node: bytes) -> None:
109 self._pending_changes[path] = node, self.flags(path)
121 self._pending_changes[path] = node, self.flags(path)
110
122
111 def __delitem__(self, path):
123 def __delitem__(self, path: bytes) -> None:
112 # TODO: should probably KeyError for already-deleted files?
124 # TODO: should probably KeyError for already-deleted files?
113 self._pending_changes[path] = None
125 self._pending_changes[path] = None
114
126
115 def filesnotin(self, other, match=None):
127 def filesnotin(self, other, match=None) -> Set[bytes]:
116 if match is not None:
128 if match is not None:
117 match = matchmod.badmatch(match, lambda path, msg: None)
129 match = matchmod.badmatch(match, lambda path, msg: None)
118 sm2 = set(other.walk(match))
130 sm2 = set(other.walk(match))
@@ -123,10 +135,18 class gittreemanifest:
123 def _dirs(self):
135 def _dirs(self):
124 return pathutil.dirs(self)
136 return pathutil.dirs(self)
125
137
126 def hasdir(self, dir):
138 def hasdir(self, dir: bytes) -> bool:
127 return dir in self._dirs
139 return dir in self._dirs
128
140
129 def diff(self, other, match=lambda x: True, clean=False):
141 def diff(
142 self,
143 other: Any, # TODO: 'manifestdict' or (better) equivalent interface
144 match: Any = lambda x: True, # TODO: Optional[matchmod.basematcher] = None,
145 clean: bool = False,
146 ) -> dict[
147 bytes,
148 tuple[tuple[bytes | None, bytes], tuple[bytes | None, bytes]] | None,
149 ]:
130 """Finds changes between the current manifest and m2.
150 """Finds changes between the current manifest and m2.
131
151
132 The result is returned as a dict with filename as key and
152 The result is returned as a dict with filename as key and
@@ -200,42 +220,43 class gittreemanifest:
200
220
201 return result
221 return result
202
222
203 def setflag(self, path, flag):
223 def setflag(self, path: bytes, flag: bytes) -> None:
204 node, unused_flag = self._resolve_entry(path)
224 node, unused_flag = self._resolve_entry(path)
205 self._pending_changes[path] = node, flag
225 self._pending_changes[path] = node, flag
206
226
207 def get(self, path, default=None):
227 def get(self, path: bytes, default=None) -> bytes | None:
208 try:
228 try:
209 return self._resolve_entry(path)[0]
229 return self._resolve_entry(path)[0]
210 except KeyError:
230 except KeyError:
211 return default
231 return default
212
232
213 def flags(self, path):
233 def flags(self, path: bytes) -> bytes:
214 try:
234 try:
215 return self._resolve_entry(path)[1]
235 return self._resolve_entry(path)[1]
216 except KeyError:
236 except KeyError:
217 return b''
237 return b''
218
238
219 def copy(self):
239 def copy(self) -> 'gittreemanifest':
220 return gittreemanifest(
240 return gittreemanifest(
221 self._git_repo, self._tree, dict(self._pending_changes)
241 self._git_repo, self._tree, dict(self._pending_changes)
222 )
242 )
223
243
224 def items(self):
244 def items(self) -> Iterator[tuple[bytes, bytes]]:
225 for f in self:
245 for f in self:
226 # TODO: build a proper iterator version of this
246 # TODO: build a proper iterator version of this
227 yield f, self[f]
247 yield f, self[f]
228
248
229 def iteritems(self):
249 def iteritems(self) -> Iterator[tuple[bytes, bytes]]:
230 return self.items()
250 return self.items()
231
251
232 def iterentries(self):
252 def iterentries(self) -> Iterator[tuple[bytes, bytes, bytes]]:
233 for f in self:
253 for f in self:
234 # TODO: build a proper iterator version of this
254 # TODO: build a proper iterator version of this
235 yield f, *self._resolve_entry(f)
255 yield f, *self._resolve_entry(f)
236
256
237 def text(self):
257 def text(self) -> ByteString:
238 assert False # TODO can this method move out of the manifest iface?
258 # TODO can this method move out of the manifest iface?
259 raise NotImplementedError
239
260
240 def _walkonetree(self, tree, match, subdir):
261 def _walkonetree(self, tree, match, subdir):
241 for te in tree:
262 for te in tree:
@@ -249,7 +270,7 class gittreemanifest:
249 elif match(realname):
270 elif match(realname):
250 yield pycompat.fsencode(realname)
271 yield pycompat.fsencode(realname)
251
272
252 def walk(self, match):
273 def walk(self, match: matchmod.basematcher) -> Iterator[bytes]:
253 # TODO: this is a very lazy way to merge in the pending
274 # TODO: this is a very lazy way to merge in the pending
254 # changes. There is absolutely room for optimization here by
275 # changes. There is absolutely room for optimization here by
255 # being clever about walking over the sets...
276 # being clever about walking over the sets...
@@ -19,15 +19,22 from typing import (
19 Iterator,
19 Iterator,
20 Mapping,
20 Mapping,
21 Protocol,
21 Protocol,
22 Set,
22 )
23 )
23
24
24 from ..i18n import _
25 from ..i18n import _
25 from .. import error
26 from .. import error
26
27
27 if typing.TYPE_CHECKING:
28 if typing.TYPE_CHECKING:
29 from typing import (
30 ByteString, # TODO: change to Buffer for 3.14
31 )
32
28 # Almost all mercurial modules are only imported in the type checking phase
33 # Almost all mercurial modules are only imported in the type checking phase
29 # to avoid circular imports
34 # to avoid circular imports
30 from .. import (
35 from .. import (
36 match as matchmod,
37 pathutil,
31 util,
38 util,
32 )
39 )
33 from ..utils import (
40 from ..utils import (
@@ -1052,7 +1059,7 class imanifestdict(Protocol):
1052 consists of a binary node and extra flags affecting that entry.
1059 consists of a binary node and extra flags affecting that entry.
1053 """
1060 """
1054
1061
1055 def __getitem__(self, path):
1062 def __getitem__(self, key: bytes) -> bytes:
1056 """Returns the binary node value for a path in the manifest.
1063 """Returns the binary node value for a path in the manifest.
1057
1064
1058 Raises ``KeyError`` if the path does not exist in the manifest.
1065 Raises ``KeyError`` if the path does not exist in the manifest.
@@ -1060,7 +1067,7 class imanifestdict(Protocol):
1060 Equivalent to ``self.find(path)[0]``.
1067 Equivalent to ``self.find(path)[0]``.
1061 """
1068 """
1062
1069
1063 def find(self, path):
1070 def find(self, path: bytes) -> tuple[bytes, bytes]:
1064 """Returns the entry for a path in the manifest.
1071 """Returns the entry for a path in the manifest.
1065
1072
1066 Returns a 2-tuple of (node, flags).
1073 Returns a 2-tuple of (node, flags).
@@ -1068,46 +1075,46 class imanifestdict(Protocol):
1068 Raises ``KeyError`` if the path does not exist in the manifest.
1075 Raises ``KeyError`` if the path does not exist in the manifest.
1069 """
1076 """
1070
1077
1071 def __len__(self):
1078 def __len__(self) -> int:
1072 """Return the number of entries in the manifest."""
1079 """Return the number of entries in the manifest."""
1073
1080
1074 def __nonzero__(self):
1081 def __nonzero__(self) -> bool:
1075 """Returns True if the manifest has entries, False otherwise."""
1082 """Returns True if the manifest has entries, False otherwise."""
1076
1083
1077 __bool__ = __nonzero__
1084 __bool__ = __nonzero__
1078
1085
1079 def set(self, path, node, flags):
1086 def set(self, path: bytes, node: bytes, flags: bytes) -> None:
1080 """Define the node value and flags for a path in the manifest.
1087 """Define the node value and flags for a path in the manifest.
1081
1088
1082 Equivalent to __setitem__ followed by setflag, but can be more efficient.
1089 Equivalent to __setitem__ followed by setflag, but can be more efficient.
1083 """
1090 """
1084
1091
1085 def __setitem__(self, path, node):
1092 def __setitem__(self, path: bytes, node: bytes) -> None:
1086 """Define the node value for a path in the manifest.
1093 """Define the node value for a path in the manifest.
1087
1094
1088 If the path is already in the manifest, its flags will be copied to
1095 If the path is already in the manifest, its flags will be copied to
1089 the new entry.
1096 the new entry.
1090 """
1097 """
1091
1098
1092 def __contains__(self, path):
1099 def __contains__(self, path: bytes) -> bool:
1093 """Whether a path exists in the manifest."""
1100 """Whether a path exists in the manifest."""
1094
1101
1095 def __delitem__(self, path):
1102 def __delitem__(self, path: bytes) -> None:
1096 """Remove a path from the manifest.
1103 """Remove a path from the manifest.
1097
1104
1098 Raises ``KeyError`` if the path is not in the manifest.
1105 Raises ``KeyError`` if the path is not in the manifest.
1099 """
1106 """
1100
1107
1101 def __iter__(self):
1108 def __iter__(self) -> Iterator[bytes]:
1102 """Iterate over paths in the manifest."""
1109 """Iterate over paths in the manifest."""
1103
1110
1104 def iterkeys(self):
1111 def iterkeys(self) -> Iterator[bytes]:
1105 """Iterate over paths in the manifest."""
1112 """Iterate over paths in the manifest."""
1106
1113
1107 def keys(self):
1114 def keys(self) -> list[bytes]:
1108 """Obtain a list of paths in the manifest."""
1115 """Obtain a list of paths in the manifest."""
1109
1116
1110 def filesnotin(self, other, match=None):
1117 def filesnotin(self, other, match=None) -> Set[bytes]:
1111 """Obtain the set of paths in this manifest but not in another.
1118 """Obtain the set of paths in this manifest but not in another.
1112
1119
1113 ``match`` is an optional matcher function to be applied to both
1120 ``match`` is an optional matcher function to be applied to both
@@ -1116,20 +1123,28 class imanifestdict(Protocol):
1116 Returns a set of paths.
1123 Returns a set of paths.
1117 """
1124 """
1118
1125
1119 def dirs(self):
1126 def dirs(self) -> pathutil.dirs:
1120 """Returns an object implementing the ``idirs`` interface."""
1127 """Returns an object implementing the ``idirs`` interface."""
1121
1128
1122 def hasdir(self, dir):
1129 def hasdir(self, dir: bytes) -> bool:
1123 """Returns a bool indicating if a directory is in this manifest."""
1130 """Returns a bool indicating if a directory is in this manifest."""
1124
1131
1125 def walk(self, match):
1132 def walk(self, match: matchmod.basematcher) -> Iterator[bytes]:
1126 """Generator of paths in manifest satisfying a matcher.
1133 """Generator of paths in manifest satisfying a matcher.
1127
1134
1128 If the matcher has explicit files listed and they don't exist in
1135 If the matcher has explicit files listed and they don't exist in
1129 the manifest, ``match.bad()`` is called for each missing file.
1136 the manifest, ``match.bad()`` is called for each missing file.
1130 """
1137 """
1131
1138
1132 def diff(self, other, match=None, clean=False):
1139 def diff(
1140 self,
1141 other: Any, # TODO: 'manifestdict' or (better) equivalent interface
1142 match: matchmod.basematcher | None = None,
1143 clean: bool = False,
1144 ) -> dict[
1145 bytes,
1146 tuple[tuple[bytes | None, bytes], tuple[bytes | None, bytes]] | None,
1147 ]:
1133 """Find differences between this manifest and another.
1148 """Find differences between this manifest and another.
1134
1149
1135 This manifest is compared to ``other``.
1150 This manifest is compared to ``other``.
@@ -1146,41 +1161,43 class imanifestdict(Protocol):
1146 are the same for the other manifest.
1161 are the same for the other manifest.
1147 """
1162 """
1148
1163
1149 def setflag(self, path, flag):
1164 def setflag(self, path: bytes, flag: bytes) -> None:
1150 """Set the flag value for a given path.
1165 """Set the flag value for a given path.
1151
1166
1152 Raises ``KeyError`` if the path is not already in the manifest.
1167 Raises ``KeyError`` if the path is not already in the manifest.
1153 """
1168 """
1154
1169
1155 def get(self, path, default=None):
1170 def get(self, path: bytes, default=None) -> bytes | None:
1156 """Obtain the node value for a path or a default value if missing."""
1171 """Obtain the node value for a path or a default value if missing."""
1157
1172
1158 def flags(self, path):
1173 def flags(self, path: bytes) -> bytes:
1159 """Return the flags value for a path (default: empty bytestring)."""
1174 """Return the flags value for a path (default: empty bytestring)."""
1160
1175
1161 def copy(self):
1176 def copy(self) -> 'imanifestdict':
1162 """Return a copy of this manifest."""
1177 """Return a copy of this manifest."""
1163
1178
1164 def items(self):
1179 def items(self) -> Iterator[tuple[bytes, bytes]]:
1165 """Returns an iterable of (path, node) for items in this manifest."""
1180 """Returns an iterable of (path, node) for items in this manifest."""
1166
1181
1167 def iteritems(self):
1182 def iteritems(self) -> Iterator[tuple[bytes, bytes]]:
1168 """Identical to items()."""
1183 """Identical to items()."""
1169
1184
1170 def iterentries(self):
1185 def iterentries(self) -> Iterator[tuple[bytes, bytes, bytes]]:
1171 """Returns an iterable of (path, node, flags) for this manifest.
1186 """Returns an iterable of (path, node, flags) for this manifest.
1172
1187
1173 Similar to ``iteritems()`` except items are a 3-tuple and include
1188 Similar to ``iteritems()`` except items are a 3-tuple and include
1174 flags.
1189 flags.
1175 """
1190 """
1176
1191
1177 def text(self):
1192 def text(self) -> ByteString:
1178 """Obtain the raw data representation for this manifest.
1193 """Obtain the raw data representation for this manifest.
1179
1194
1180 Result is used to create a manifest revision.
1195 Result is used to create a manifest revision.
1181 """
1196 """
1182
1197
1183 def fastdelta(self, base, changes):
1198 def fastdelta(
1199 self, base: ByteString, changes: Iterable[tuple[bytes, bool]]
1200 ) -> tuple[ByteString, ByteString]:
1184 """Obtain a delta between this manifest and another given changes.
1201 """Obtain a delta between this manifest and another given changes.
1185
1202
1186 ``base`` in the raw data representation for another manifest.
1203 ``base`` in the raw data representation for another manifest.
General Comments 0
You need to be logged in to leave comments. Login now