##// END OF EJS Templates
manifest: add many type annotations to the manifest module...
marmoute -
r52667:79e0ee35 default
parent child Browse files
Show More
@@ -12,7 +12,17 b' import struct'
12 12 import weakref
13 13
14 14 from typing import (
15 ByteString,
16 Callable,
17 Dict,
15 18 Iterable,
19 Iterator,
20 List,
21 Optional,
22 Set,
23 Tuple,
24 Union,
25 cast,
16 26 )
17 27
18 28 from .i18n import _
@@ -47,7 +57,7 b' propertycache = util.propertycache'
47 57 FASTDELTA_TEXTDIFF_THRESHOLD = 1000
48 58
49 59
50 def _parse(nodelen, data):
60 def _parse(nodelen, data: bytes):
51 61 # This method does a little bit of excessive-looking
52 62 # precondition checking. This is so that the behavior of this
53 63 # class exactly matches its C counterpart to try and help
@@ -88,21 +98,23 b' def _text(it):'
88 98
89 99
90 100 class lazymanifestiter:
91 def __init__(self, lm):
101 def __init__(self, lm: '_LazyManifest') -> None:
92 102 self.pos = 0
93 103 self.lm = lm
94 104
95 def __iter__(self):
105 def __iter__(self) -> 'lazymanifestiter':
96 106 return self
97 107
98 def next(self):
108 def next(self) -> bytes:
99 109 try:
100 110 data, pos = self.lm._get(self.pos)
101 111 except IndexError:
102 112 raise StopIteration
103 113 if pos == -1:
114 assert isinstance(data, tuple)
104 115 self.pos += 1
105 116 return data[0]
117 assert isinstance(data, bytes)
106 118 self.pos += 1
107 119 zeropos = data.find(b'\x00', pos)
108 120 return data[pos:zeropos]
@@ -111,21 +123,23 b' class lazymanifestiter:'
111 123
112 124
113 125 class lazymanifestiterentries:
114 def __init__(self, lm):
126 def __init__(self, lm: '_LazyManifest') -> None:
115 127 self.lm = lm
116 128 self.pos = 0
117 129
118 def __iter__(self):
130 def __iter__(self) -> 'lazymanifestiterentries':
119 131 return self
120 132
121 def next(self):
133 def next(self) -> Tuple[bytes, bytes, bytes]:
122 134 try:
123 135 data, pos = self.lm._get(self.pos)
124 136 except IndexError:
125 137 raise StopIteration
126 138 if pos == -1:
139 assert isinstance(data, tuple)
127 140 self.pos += 1
128 141 return data
142 assert isinstance(data, bytes)
129 143 zeropos = data.find(b'\x00', pos)
130 144 nlpos = data.find(b'\n', pos)
131 145 if zeropos == -1 or nlpos == -1 or nlpos < zeropos:
@@ -181,12 +195,12 b' class _LazyManifest:'
181 195
182 196 def __init__(
183 197 self,
184 nodelen,
185 data,
198 nodelen: int,
199 data: bytes,
186 200 positions=None,
187 201 extrainfo=None,
188 202 extradata=None,
189 hasremovals=False,
203 hasremovals: bool = False,
190 204 ):
191 205 self._nodelen = nodelen
192 206 if positions is None:
@@ -202,7 +216,7 b' class _LazyManifest:'
202 216 self.data = data
203 217 self.hasremovals = hasremovals
204 218
205 def findlines(self, data):
219 def findlines(self, data: bytes) -> List[int]:
206 220 if not data:
207 221 return []
208 222 pos = data.find(b"\n")
@@ -219,7 +233,9 b' class _LazyManifest:'
219 233 pos = data.find(b"\n", pos + 1)
220 234 return positions
221 235
222 def _get(self, index):
236 def _get(
237 self, index: int
238 ) -> Tuple[Union[bytes, Tuple[bytes, bytes, bytes]], int]:
223 239 # get the position encoded in pos:
224 240 # positive number is an index in 'data'
225 241 # negative number is in extrapieces
@@ -228,12 +244,12 b' class _LazyManifest:'
228 244 return self.data, pos
229 245 return self.extradata[-pos - 1], -1
230 246
231 def _getkey(self, pos):
247 def _getkey(self, pos) -> bytes:
232 248 if pos >= 0:
233 249 return self.data[pos : self.data.find(b'\x00', pos + 1)]
234 250 return self.extradata[-pos - 1][0]
235 251
236 def bsearch(self, key):
252 def bsearch(self, key: bytes) -> int:
237 253 first = 0
238 254 last = len(self.positions) - 1
239 255
@@ -251,7 +267,7 b' class _LazyManifest:'
251 267 first = midpoint + 1
252 268 return -1
253 269
254 def bsearch2(self, key):
270 def bsearch2(self, key: bytes) -> Tuple[int, bool]:
255 271 # same as the above, but will always return the position
256 272 # done for performance reasons
257 273 first = 0
@@ -271,10 +287,10 b' class _LazyManifest:'
271 287 first = midpoint + 1
272 288 return (first, False)
273 289
274 def __contains__(self, key):
290 def __contains__(self, key: bytes) -> bool:
275 291 return self.bsearch(key) != -1
276 292
277 def __getitem__(self, key):
293 def __getitem__(self, key: bytes) -> Tuple[bytes, bytes]:
278 294 if not isinstance(key, bytes):
279 295 raise TypeError(b"getitem: manifest keys must be a bytes.")
280 296 needle = self.bsearch(key)
@@ -282,7 +298,10 b' class _LazyManifest:'
282 298 raise KeyError
283 299 data, pos = self._get(needle)
284 300 if pos == -1:
301 assert isinstance(data, tuple)
285 302 return (data[1], data[2])
303
304 assert isinstance(data, bytes)
286 305 zeropos = data.find(b'\x00', pos)
287 306 nlpos = data.find(b'\n', zeropos)
288 307 assert 0 <= needle <= len(self.positions)
@@ -300,7 +319,7 b' class _LazyManifest:'
300 319 hashval = unhexlify(data, self.extrainfo[needle], zeropos + 1, hlen)
301 320 return (hashval, flags)
302 321
303 def __delitem__(self, key):
322 def __delitem__(self, key: bytes) -> None:
304 323 needle, found = self.bsearch2(key)
305 324 if not found:
306 325 raise KeyError
@@ -313,7 +332,7 b' class _LazyManifest:'
313 332 self.data = self.data[:cur] + b'\x00' + self.data[cur + 1 :]
314 333 self.hasremovals = True
315 334
316 def __setitem__(self, key, value):
335 def __setitem__(self, key: bytes, value: Tuple[bytes, bytes]):
317 336 if not isinstance(key, bytes):
318 337 raise TypeError(b"setitem: manifest keys must be a byte string.")
319 338 if not isinstance(value, tuple) or len(value) != 2:
@@ -348,7 +367,7 b' class _LazyManifest:'
348 367 self.extrainfo[:needle] + [0] + self.extrainfo[needle:]
349 368 )
350 369
351 def copy(self):
370 def copy(self) -> '_LazyManifest':
352 371 # XXX call _compact like in C?
353 372 return _lazymanifest(
354 373 self._nodelen,
@@ -359,7 +378,7 b' class _LazyManifest:'
359 378 self.hasremovals,
360 379 )
361 380
362 def _compact(self):
381 def _compact(self) -> None:
363 382 # hopefully not called TOO often
364 383 if len(self.extradata) == 0 and not self.hasremovals:
365 384 return
@@ -418,16 +437,23 b' class _LazyManifest:'
418 437 self.hasremovals = False
419 438 self.extradata = []
420 439
421 def _pack(self, d):
440 def _pack(self, d: Tuple[bytes, bytes, bytes]) -> bytes:
422 441 n = d[1]
423 442 assert len(n) in (20, 32)
424 443 return d[0] + b'\x00' + hex(n) + d[2] + b'\n'
425 444
426 def text(self):
445 def text(self) -> ByteString:
427 446 self._compact()
428 447 return self.data
429 448
430 def diff(self, m2, clean=False):
449 def diff(
450 self, m2: '_LazyManifest', clean: bool = False
451 ) -> Dict[
452 bytes,
453 Optional[
454 Tuple[Tuple[Optional[bytes], bytes], Tuple[Optional[bytes], bytes]]
455 ],
456 ]:
431 457 '''Finds changes between the current manifest and m2.'''
432 458 # XXX think whether efficiency matters here
433 459 diff = {}
@@ -448,19 +474,19 b' class _LazyManifest:'
448 474
449 475 return diff
450 476
451 def iterentries(self):
477 def iterentries(self) -> lazymanifestiterentries:
452 478 return lazymanifestiterentries(self)
453 479
454 def iterkeys(self):
480 def iterkeys(self) -> lazymanifestiter:
455 481 return lazymanifestiter(self)
456 482
457 def __iter__(self):
483 def __iter__(self) -> lazymanifestiter:
458 484 return lazymanifestiter(self)
459 485
460 def __len__(self):
486 def __len__(self) -> int:
461 487 return len(self.positions)
462 488
463 def filtercopy(self, filterfn):
489 def filtercopy(self, filterfn: Callable[[bytes], bool]) -> '_LazyManifest':
464 490 # XXX should be optimized
465 491 c = _lazymanifest(self._nodelen, b'')
466 492 for f, n, fl in self.iterentries():
@@ -476,50 +502,50 b' except AttributeError:'
476 502
477 503
478 504 class ManifestDict:
479 def __init__(self, nodelen, data=b''):
505 def __init__(self, nodelen: int, data: ByteString = b''):
480 506 self._nodelen = nodelen
481 507 self._lm = _lazymanifest(nodelen, data)
482 508
483 def __getitem__(self, key):
509 def __getitem__(self, key: bytes) -> bytes:
484 510 return self._lm[key][0]
485 511
486 def find(self, key):
512 def find(self, key: bytes) -> Tuple[bytes, bytes]:
487 513 return self._lm[key]
488 514
489 def __len__(self):
515 def __len__(self) -> int:
490 516 return len(self._lm)
491 517
492 def __nonzero__(self):
518 def __nonzero__(self) -> bool:
493 519 # nonzero is covered by the __len__ function, but implementing it here
494 520 # makes it easier for extensions to override.
495 521 return len(self._lm) != 0
496 522
497 523 __bool__ = __nonzero__
498 524
499 def set(self, key, node, flags):
525 def set(self, key: bytes, node: bytes, flags: bytes) -> None:
500 526 self._lm[key] = node, flags
501 527
502 def __setitem__(self, key, node):
528 def __setitem__(self, key: bytes, node: bytes) -> None:
503 529 self._lm[key] = node, self.flags(key)
504 530
505 def __contains__(self, key):
531 def __contains__(self, key: bytes) -> bool:
506 532 if key is None:
507 533 return False
508 534 return key in self._lm
509 535
510 def __delitem__(self, key):
536 def __delitem__(self, key: bytes) -> bool:
511 537 del self._lm[key]
512 538
513 def __iter__(self):
539 def __iter__(self) -> Iterator[bytes]:
514 540 return self._lm.__iter__()
515 541
516 def iterkeys(self):
542 def iterkeys(self) -> Iterator[bytes]:
517 543 return self._lm.iterkeys()
518 544
519 def keys(self):
545 def keys(self) -> List[bytes]:
520 546 return list(self.iterkeys())
521 547
522 def filesnotin(self, m2, match=None):
548 def filesnotin(self, m2, match=None) -> Set[bytes]:
523 549 '''Set of files in this manifest that are not in the other'''
524 550 if match is not None:
525 551 match = matchmod.badmatch(match, lambda path, msg: None)
@@ -528,16 +554,16 b' class ManifestDict:'
528 554 return {f for f in self if f not in m2}
529 555
530 556 @propertycache
531 def _dirs(self):
557 def _dirs(self) -> pathutil.dirs:
532 558 return pathutil.dirs(self)
533 559
534 def dirs(self):
560 def dirs(self) -> pathutil.dirs:
535 561 return self._dirs
536 562
537 def hasdir(self, dir):
563 def hasdir(self, dir: bytes) -> bool:
538 564 return dir in self._dirs
539 565
540 def _filesfastpath(self, match):
566 def _filesfastpath(self, match: matchmod.basematcher) -> bool:
541 567 """Checks whether we can correctly and quickly iterate over matcher
542 568 files instead of over manifest files."""
543 569 files = match.files()
@@ -546,7 +572,7 b' class ManifestDict:'
546 572 or (match.prefix() and all(fn in self for fn in files))
547 573 )
548 574
549 def walk(self, match):
575 def walk(self, match: matchmod.basematcher) -> Iterator[bytes]:
550 576 """Generates matching file names.
551 577
552 578 Equivalent to manifest.matches(match).iterkeys(), but without creating
@@ -583,7 +609,7 b' class ManifestDict:'
583 609 if not self.hasdir(fn):
584 610 match.bad(fn, None)
585 611
586 def _matches(self, match):
612 def _matches(self, match: matchmod.basematcher) -> 'ManifestDict':
587 613 '''generate a new manifest filtered by the match argument'''
588 614 if match.always():
589 615 return self.copy()
@@ -600,7 +626,17 b' class ManifestDict:'
600 626 m._lm = self._lm.filtercopy(match)
601 627 return m
602 628
603 def diff(self, m2, match=None, clean=False):
629 def diff(
630 self,
631 m2: 'ManifestDict',
632 match: Optional[matchmod.basematcher] = None,
633 clean: bool = False,
634 ) -> Dict[
635 bytes,
636 Optional[
637 Tuple[Tuple[Optional[bytes], bytes], Tuple[Optional[bytes], bytes]]
638 ],
639 ]:
604 640 """Finds changes between the current manifest and m2.
605 641
606 642 Args:
@@ -621,42 +657,44 b' class ManifestDict:'
621 657 return m1.diff(m2, clean=clean)
622 658 return self._lm.diff(m2._lm, clean)
623 659
624 def setflag(self, key, flag):
660 def setflag(self, key: bytes, flag: bytes) -> None:
625 661 if flag not in _manifestflags:
626 662 raise TypeError(b"Invalid manifest flag set.")
627 663 self._lm[key] = self[key], flag
628 664
629 def get(self, key, default=None):
665 def get(self, key: bytes, default=None) -> Optional[bytes]:
630 666 try:
631 667 return self._lm[key][0]
632 668 except KeyError:
633 669 return default
634 670
635 def flags(self, key):
671 def flags(self, key: bytes) -> bytes:
636 672 try:
637 673 return self._lm[key][1]
638 674 except KeyError:
639 675 return b''
640 676
641 def copy(self):
677 def copy(self) -> 'ManifestDict':
642 678 c = manifestdict(self._nodelen)
643 679 c._lm = self._lm.copy()
644 680 return c
645 681
646 def items(self):
682 def items(self) -> Iterator[Tuple[bytes, bytes]]:
647 683 return (x[:2] for x in self._lm.iterentries())
648 684
649 def iteritems(self):
685 def iteritems(self) -> Iterator[Tuple[bytes, bytes]]:
650 686 return (x[:2] for x in self._lm.iterentries())
651 687
652 def iterentries(self):
688 def iterentries(self) -> Iterator[Tuple[bytes, bytes, bytes]]:
653 689 return self._lm.iterentries()
654 690
655 def text(self):
691 def text(self) -> ByteString:
656 692 # most likely uses native version
657 693 return self._lm.text()
658 694
659 def fastdelta(self, base, changes):
695 def fastdelta(
696 self, base: ByteString, changes: Iterable[Tuple[bytes, bool]]
697 ) -> Tuple[ByteString, ByteString]:
660 698 """Given a base manifest text as a bytearray and a list of changes
661 699 relative to that text, compute a delta that can be used by revlog.
662 700 """
@@ -715,17 +753,17 b' class ManifestDict:'
715 753 manifestdict = interfaceutil.implementer(repository.imanifestdict)(ManifestDict)
716 754
717 755
718 def _msearch(m, s, lo=0, hi=None):
756 def _msearch(
757 m: ByteString, s: bytes, lo: int = 0, hi: Optional[int] = None
758 ) -> Tuple[int, int]:
719 759 """return a tuple (start, end) that says where to find s within m.
720 760
721 761 If the string is found m[start:end] are the line containing
722 762 that string. If start == end the string was not found and
723 763 they indicate the proper sorted insertion point.
724
725 m should be a buffer, a memoryview or a byte string.
726 s is a byte string"""
727
728 def advance(i, c):
764 """
765
766 def advance(i: int, c: bytes):
729 767 while i < lenm and m[i : i + 1] != c:
730 768 i += 1
731 769 return i
@@ -758,7 +796,7 b' def _msearch(m, s, lo=0, hi=None):'
758 796 return (lo, lo)
759 797
760 798
761 def _checkforbidden(l):
799 def _checkforbidden(l: Iterable[bytes]) -> None:
762 800 """Check filenames for illegal characters."""
763 801 for f in l:
764 802 if b'\n' in f or b'\r' in f:
@@ -770,7 +808,10 b' def _checkforbidden(l):'
770 808
771 809 # apply the changes collected during the bisect loop to our addlist
772 810 # return a delta suitable for addrevision
773 def _addlistdelta(addlist, x):
811 def _addlistdelta(
812 addlist: ByteString,
813 x: Iterable[Tuple[int, int, bytes]],
814 ) -> Tuple[bytes, ByteString]:
774 815 # for large addlist arrays, building a new array is cheaper
775 816 # than repeatedly modifying the existing one
776 817 currentposition = 0
@@ -792,7 +833,7 b' def _addlistdelta(addlist, x):'
792 833 return deltatext, newaddlist
793 834
794 835
795 def _splittopdir(f):
836 def _splittopdir(f: bytes) -> Tuple[bytes, bytes]:
796 837 if b'/' in f:
797 838 dir, subpath = f.split(b'/', 1)
798 839 return dir + b'/', subpath
@@ -804,7 +845,7 b' def _splittopdir(f):'
804 845
805 846
806 847 class TreeManifest:
807 def __init__(self, nodeconstants, dir=b'', text=b''):
848 def __init__(self, nodeconstants, dir: bytes = b'', text: bytes = b''):
808 849 self._dir = dir
809 850 self.nodeconstants = nodeconstants
810 851 self._node = self.nodeconstants.nullid
@@ -812,10 +853,13 b' class TreeManifest:'
812 853 self._loadfunc = _noop
813 854 self._copyfunc = _noop
814 855 self._dirty = False
815 self._dirs = {}
816 self._lazydirs = {}
856 self._dirs: Dict[bytes, 'TreeManifest'] = {}
857 self._lazydirs: Dict[
858 bytes,
859 Tuple[bytes, Callable[[bytes, bytes], 'TreeManifest'], bool],
860 ] = {}
817 861 # Using _lazymanifest here is a little slower than plain old dicts
818 self._files = {}
862 self._files: Dict[bytes, bytes] = {}
819 863 self._flags = {}
820 864 if text:
821 865
@@ -827,10 +871,10 b' class TreeManifest:'
827 871 self.parse(text, readsubtree)
828 872 self._dirty = True # Mark flat manifest dirty after parsing
829 873
830 def _subpath(self, path):
874 def _subpath(self, path: bytes) -> bytes:
831 875 return self._dir + path
832 876
833 def _loadalllazy(self):
877 def _loadalllazy(self) -> None:
834 878 selfdirs = self._dirs
835 879 subpath = self._subpath
836 880 for d, (node, readsubtree, docopy) in self._lazydirs.items():
@@ -840,7 +884,7 b' class TreeManifest:'
840 884 selfdirs[d] = readsubtree(subpath(d), node)
841 885 self._lazydirs.clear()
842 886
843 def _loadlazy(self, d):
887 def _loadlazy(self, d: bytes) -> None:
844 888 v = self._lazydirs.get(d)
845 889 if v is not None:
846 890 node, readsubtree, docopy = v
@@ -850,19 +894,23 b' class TreeManifest:'
850 894 self._dirs[d] = readsubtree(self._subpath(d), node)
851 895 del self._lazydirs[d]
852 896
853 def _loadchildrensetlazy(self, visit):
897 def _loadchildrensetlazy(
898 self, visit: Union[Set[bytes], bytes]
899 ) -> Optional[Set[bytes]]:
854 900 if not visit:
855 901 return None
856 902 if visit == b'all' or visit == b'this':
857 903 self._loadalllazy()
858 904 return None
859 905
906 visit = cast(Set[bytes], visit)
907
860 908 loadlazy = self._loadlazy
861 909 for k in visit:
862 910 loadlazy(k + b'/')
863 911 return visit
864 912
865 def _loaddifflazy(self, t1, t2):
913 def _loaddifflazy(self, t1: 'TreeManifest', t2: 'TreeManifest'):
866 914 """load items in t1 and t2 if they're needed for diffing.
867 915
868 916 The criteria currently is:
@@ -884,7 +932,7 b' class TreeManifest:'
884 932 t1._loadlazy(d)
885 933 t2._loadlazy(d)
886 934
887 def __len__(self):
935 def __len__(self) -> int:
888 936 self._load()
889 937 size = len(self._files)
890 938 self._loadalllazy()
@@ -892,13 +940,13 b' class TreeManifest:'
892 940 size += m.__len__()
893 941 return size
894 942
895 def __nonzero__(self):
896 # Faster than "__len() != 0" since it avoids loading sub-manifests
943 def __nonzero__(self) -> bool:
944 # Faster than "__len__() != 0" since it avoids loading sub-manifests
897 945 return not self._isempty()
898 946
899 947 __bool__ = __nonzero__
900 948
901 def _isempty(self):
949 def _isempty(self) -> bool:
902 950 self._load() # for consistency; already loaded by all callers
903 951 # See if we can skip loading everything.
904 952 if self._files or (
@@ -909,7 +957,7 b' class TreeManifest:'
909 957 return not self._dirs or all(m._isempty() for m in self._dirs.values())
910 958
911 959 @encoding.strmethod
912 def __repr__(self):
960 def __repr__(self) -> bytes:
913 961 return (
914 962 b'<treemanifest dir=%s, node=%s, loaded=%r, dirty=%r at 0x%x>'
915 963 % (
@@ -921,23 +969,25 b' class TreeManifest:'
921 969 )
922 970 )
923 971
924 def dir(self):
972 def dir(self) -> bytes:
925 973 """The directory that this tree manifest represents, including a
926 974 trailing '/'. Empty string for the repo root directory."""
927 975 return self._dir
928 976
929 def node(self):
977 def node(self) -> bytes:
930 978 """This node of this instance. nullid for unsaved instances. Should
931 979 be updated when the instance is read or written from a revlog.
932 980 """
933 981 assert not self._dirty
934 982 return self._node
935 983
936 def setnode(self, node):
984 def setnode(self, node: bytes) -> None:
937 985 self._node = node
938 986 self._dirty = False
939 987
940 def iterentries(self):
988 def iterentries(
989 self,
990 ) -> Iterator[Tuple[bytes, Union[bytes, 'TreeManifest'], bytes]]:
941 991 self._load()
942 992 self._loadalllazy()
943 993 for p, n in sorted(
@@ -949,7 +999,7 b' class TreeManifest:'
949 999 for x in n.iterentries():
950 1000 yield x
951 1001
952 def items(self):
1002 def items(self) -> Iterator[Tuple[bytes, Union[bytes, 'TreeManifest']]]:
953 1003 self._load()
954 1004 self._loadalllazy()
955 1005 for p, n in sorted(
@@ -963,7 +1013,7 b' class TreeManifest:'
963 1013
964 1014 iteritems = items
965 1015
966 def iterkeys(self):
1016 def iterkeys(self) -> Iterator[bytes]:
967 1017 self._load()
968 1018 self._loadalllazy()
969 1019 for p in sorted(itertools.chain(self._dirs, self._files)):
@@ -973,13 +1023,13 b' class TreeManifest:'
973 1023 for f in self._dirs[p]:
974 1024 yield f
975 1025
976 def keys(self):
1026 def keys(self) -> List[bytes]:
977 1027 return list(self.iterkeys())
978 1028
979 def __iter__(self):
1029 def __iter__(self) -> Iterator[bytes]:
980 1030 return self.iterkeys()
981 1031
982 def __contains__(self, f):
1032 def __contains__(self, f: bytes) -> bool:
983 1033 if f is None:
984 1034 return False
985 1035 self._load()
@@ -994,7 +1044,7 b' class TreeManifest:'
994 1044 else:
995 1045 return f in self._files
996 1046
997 def get(self, f, default=None):
1047 def get(self, f: bytes, default: Optional[bytes] = None) -> Optional[bytes]:
998 1048 self._load()
999 1049 dir, subpath = _splittopdir(f)
1000 1050 if dir:
@@ -1006,7 +1056,7 b' class TreeManifest:'
1006 1056 else:
1007 1057 return self._files.get(f, default)
1008 1058
1009 def __getitem__(self, f):
1059 def __getitem__(self, f: bytes) -> bytes:
1010 1060 self._load()
1011 1061 dir, subpath = _splittopdir(f)
1012 1062 if dir:
@@ -1016,7 +1066,7 b' class TreeManifest:'
1016 1066 else:
1017 1067 return self._files[f]
1018 1068
1019 def flags(self, f):
1069 def flags(self, f: bytes) -> bytes:
1020 1070 self._load()
1021 1071 dir, subpath = _splittopdir(f)
1022 1072 if dir:
@@ -1030,7 +1080,7 b' class TreeManifest:'
1030 1080 return b''
1031 1081 return self._flags.get(f, b'')
1032 1082
1033 def find(self, f):
1083 def find(self, f: bytes) -> Tuple[bytes, bytes]:
1034 1084 self._load()
1035 1085 dir, subpath = _splittopdir(f)
1036 1086 if dir:
@@ -1040,7 +1090,7 b' class TreeManifest:'
1040 1090 else:
1041 1091 return self._files[f], self._flags.get(f, b'')
1042 1092
1043 def __delitem__(self, f):
1093 def __delitem__(self, f: bytes) -> None:
1044 1094 self._load()
1045 1095 dir, subpath = _splittopdir(f)
1046 1096 if dir:
@@ -1056,7 +1106,7 b' class TreeManifest:'
1056 1106 del self._flags[f]
1057 1107 self._dirty = True
1058 1108
1059 def set(self, f, node, flags):
1109 def set(self, f: bytes, node: bytes, flags: bytes) -> None:
1060 1110 """Set both the node and the flags for path f."""
1061 1111 assert node is not None
1062 1112 if flags not in _manifestflags:
@@ -1076,7 +1126,7 b' class TreeManifest:'
1076 1126 self._flags[f] = flags
1077 1127 self._dirty = True
1078 1128
1079 def __setitem__(self, f, n):
1129 def __setitem__(self, f: bytes, n: bytes) -> None:
1080 1130 assert n is not None
1081 1131 self._load()
1082 1132 dir, subpath = _splittopdir(f)
@@ -1095,7 +1145,7 b' class TreeManifest:'
1095 1145 self._files[f] = n
1096 1146 self._dirty = True
1097 1147
1098 def _load(self):
1148 def _load(self) -> None:
1099 1149 if self._loadfunc is not _noop:
1100 1150 lf, self._loadfunc = self._loadfunc, _noop
1101 1151 lf(self)
@@ -1103,7 +1153,7 b' class TreeManifest:'
1103 1153 cf, self._copyfunc = self._copyfunc, _noop
1104 1154 cf(self)
1105 1155
1106 def setflag(self, f, flags):
1156 def setflag(self, f: bytes, flags: bytes) -> None:
1107 1157 """Set the flags (symlink, executable) for path f."""
1108 1158 if flags not in _manifestflags:
1109 1159 raise TypeError(b"Invalid manifest flag set.")
@@ -1120,7 +1170,7 b' class TreeManifest:'
1120 1170 self._flags[f] = flags
1121 1171 self._dirty = True
1122 1172
1123 def copy(self):
1173 def copy(self) -> 'TreeManifest':
1124 1174 copy = treemanifest(self.nodeconstants, self._dir)
1125 1175 copy._node = self._node
1126 1176 copy._dirty = self._dirty
@@ -1145,7 +1195,9 b' class TreeManifest:'
1145 1195 copy._copyfunc = self._copyfunc
1146 1196 return copy
1147 1197
1148 def filesnotin(self, m2, match=None):
1198 def filesnotin(
1199 self, m2: 'TreeManifest', match: Optional[matchmod.basematcher] = None
1200 ) -> Set[bytes]:
1149 1201 '''Set of files in this manifest that are not in the other'''
1150 1202 if match and not match.always():
1151 1203 m1 = self._matches(match)
@@ -1175,13 +1227,13 b' class TreeManifest:'
1175 1227 return files
1176 1228
1177 1229 @propertycache
1178 def _alldirs(self):
1230 def _alldirs(self) -> pathutil.dirs:
1179 1231 return pathutil.dirs(self)
1180 1232
1181 def dirs(self):
1233 def dirs(self) -> pathutil.dirs:
1182 1234 return self._alldirs
1183 1235
1184 def hasdir(self, dir):
1236 def hasdir(self, dir: bytes) -> bool:
1185 1237 self._load()
1186 1238 topdir, subdir = _splittopdir(dir)
1187 1239 if topdir:
@@ -1192,7 +1244,7 b' class TreeManifest:'
1192 1244 dirslash = dir + b'/'
1193 1245 return dirslash in self._dirs or dirslash in self._lazydirs
1194 1246
1195 def walk(self, match):
1247 def walk(self, match: matchmod.basematcher) -> Iterator[bytes]:
1196 1248 """Generates matching file names.
1197 1249
1198 1250 It also reports nonexistent files by marking them bad with match.bad().
@@ -1218,7 +1270,7 b' class TreeManifest:'
1218 1270 if not self.hasdir(fn):
1219 1271 match.bad(fn, None)
1220 1272
1221 def _walk(self, match):
1273 def _walk(self, match: matchmod.basematcher) -> Iterator[bytes]:
1222 1274 '''Recursively generates matching file names for walk().'''
1223 1275 visit = match.visitchildrenset(self._dir[:-1])
1224 1276 if not visit:
@@ -1237,13 +1289,13 b' class TreeManifest:'
1237 1289 for f in self._dirs[p]._walk(match):
1238 1290 yield f
1239 1291
1240 def _matches(self, match):
1292 def _matches(self, match: matchmod.basematcher) -> 'TreeManifest':
1241 1293 """recursively generate a new manifest filtered by the match argument."""
1242 1294 if match.always():
1243 1295 return self.copy()
1244 1296 return self._matches_inner(match)
1245 1297
1246 def _matches_inner(self, match):
1298 def _matches_inner(self, match: matchmod.basematcher) -> 'TreeManifest':
1247 1299 if match.always():
1248 1300 return self.copy()
1249 1301
@@ -1284,10 +1336,22 b' class TreeManifest:'
1284 1336 ret._dirty = True
1285 1337 return ret
1286 1338
1287 def fastdelta(self, base, changes):
1339 def fastdelta(
1340 self, base: ByteString, changes: Iterable[Tuple[bytes, bool]]
1341 ) -> ByteString:
1288 1342 raise FastdeltaUnavailable()
1289 1343
1290 def diff(self, m2, match=None, clean=False):
1344 def diff(
1345 self,
1346 m2: 'TreeManifest',
1347 match: Optional[matchmod.basematcher] = None,
1348 clean: bool = False,
1349 ) -> Dict[
1350 bytes,
1351 Optional[
1352 Tuple[Tuple[Optional[bytes], bytes], Tuple[Optional[bytes], bytes]]
1353 ],
1354 ]:
1291 1355 """Finds changes between the current manifest and m2.
1292 1356
1293 1357 Args:
@@ -1348,10 +1412,14 b' class TreeManifest:'
1348 1412 _iterativediff(t1, t2, stackls)
1349 1413 return result
1350 1414
1351 def unmodifiedsince(self, m2):
1415 def unmodifiedsince(self, m2: 'TreeManifest') -> bool:
1352 1416 return not self._dirty and not m2._dirty and self._node == m2._node
1353 1417
1354 def parse(self, text, readsubtree):
1418 def parse(
1419 self,
1420 text: bytes,
1421 readsubtree: Callable[[bytes, bytes], 'TreeManifest'],
1422 ) -> None:
1355 1423 selflazy = self._lazydirs
1356 1424 for f, n, fl in _parse(self._nodelen, text):
1357 1425 if fl == b't':
@@ -1374,12 +1442,12 b' class TreeManifest:'
1374 1442 if fl:
1375 1443 self._flags[f] = fl
1376 1444
1377 def text(self):
1445 def text(self) -> ByteString:
1378 1446 """Get the full data of this manifest as a bytestring."""
1379 1447 self._load()
1380 1448 return _text(self.iterentries())
1381 1449
1382 def dirtext(self):
1450 def dirtext(self) -> ByteString:
1383 1451 """Get the full data of this directory as a bytestring. Make sure that
1384 1452 any submanifests have been written first, so their nodeids are correct.
1385 1453 """
@@ -1390,14 +1458,32 b' class TreeManifest:'
1390 1458 files = [(f, self._files[f], flags(f)) for f in self._files]
1391 1459 return _text(sorted(dirs + files + lazydirs))
1392 1460
1393 def read(self, gettext, readsubtree):
1461 def read(
1462 self,
1463 gettext: Callable[[], ByteString],
1464 readsubtree: Callable[[bytes, bytes], 'TreeManifest'],
1465 ) -> None:
1394 1466 def _load_for_read(s):
1395 1467 s.parse(gettext(), readsubtree)
1396 1468 s._dirty = False
1397 1469
1398 1470 self._loadfunc = _load_for_read
1399 1471
1400 def writesubtrees(self, m1, m2, writesubtree, match):
1472 def writesubtrees(
1473 self,
1474 m1: 'TreeManifest',
1475 m2: 'TreeManifest',
1476 writesubtree: Callable[
1477 [
1478 Callable[['TreeManifest'], None],
1479 bytes,
1480 bytes,
1481 matchmod.basematcher,
1482 ],
1483 None,
1484 ],
1485 match: matchmod.basematcher,
1486 ) -> None:
1401 1487 self._load() # for consistency; should never have any effect here
1402 1488 m1._load()
1403 1489 m2._load()
@@ -1425,7 +1511,9 b' class TreeManifest:'
1425 1511 subp1, subp2 = subp2, subp1
1426 1512 writesubtree(subm, subp1, subp2, match)
1427 1513
1428 def walksubtrees(self, matcher=None):
1514 def walksubtrees(
1515 self, matcher: Optional[matchmod.basematcher] = None
1516 ) -> Iterator['TreeManifest']:
1429 1517 """Returns an iterator of the subtrees of this manifest, including this
1430 1518 manifest itself.
1431 1519
@@ -1716,8 +1804,8 b' class ManifestRevlog:'
1716 1804 link,
1717 1805 p1,
1718 1806 p2,
1719 added: Iterable[Iterable],
1720 removed: Iterable[Iterable],
1807 added: Iterable[bytes],
1808 removed: Iterable[bytes],
1721 1809 readtree=None,
1722 1810 match=None,
1723 1811 ):
@@ -1959,6 +2047,10 b' manifestrevlog = interfaceutil.implement'
1959 2047 )
1960 2048
1961 2049
2050 AnyManifestCtx = Union['ManifestCtx', 'TreeManifestCtx']
2051 AnyManifestDict = Union[ManifestDict, TreeManifest]
2052
2053
1962 2054 @interfaceutil.implementer(repository.imanifestlog)
1963 2055 class manifestlog:
1964 2056 """A collection class representing the collection of manifest snapshots
@@ -1997,7 +2089,9 b' class manifestlog:'
1997 2089 """
1998 2090 return self.get(b'', node)
1999 2091
2000 def get(self, tree, node, verify=True):
2092 def get(
2093 self, tree: bytes, node: bytes, verify: bool = True
2094 ) -> AnyManifestCtx:
2001 2095 """Retrieves the manifest instance for the given node. Throws a
2002 2096 LookupError if not found.
2003 2097
@@ -2047,14 +2141,14 b' class manifestlog:'
2047 2141 def getstorage(self, tree):
2048 2142 return self._rootstore.dirlog(tree)
2049 2143
2050 def clearcaches(self, clear_persisted_data=False):
2144 def clearcaches(self, clear_persisted_data: bool = False) -> None:
2051 2145 self._dirmancache.clear()
2052 2146 self._rootstore.clearcaches(clear_persisted_data=clear_persisted_data)
2053 2147
2054 def rev(self, node):
2148 def rev(self, node) -> int:
2055 2149 return self._rootstore.rev(node)
2056 2150
2057 def update_caches(self, transaction):
2151 def update_caches(self, transaction) -> None:
2058 2152 return self._rootstore._revlog.update_caches(transaction=transaction)
2059 2153
2060 2154
@@ -2063,15 +2157,15 b' class MemManifestCtx:'
2063 2157 self._manifestlog = manifestlog
2064 2158 self._manifestdict = manifestdict(manifestlog.nodeconstants.nodelen)
2065 2159
2066 def _storage(self):
2160 def _storage(self) -> ManifestRevlog:
2067 2161 return self._manifestlog.getstorage(b'')
2068 2162
2069 def copy(self):
2163 def copy(self) -> 'MemManifestCtx':
2070 2164 memmf = memmanifestctx(self._manifestlog)
2071 2165 memmf._manifestdict = self.read().copy()
2072 2166 return memmf
2073 2167
2074 def read(self):
2168 def read(self) -> 'ManifestDict':
2075 2169 return self._manifestdict
2076 2170
2077 2171 def write(self, transaction, link, p1, p2, added, removed, match=None):
@@ -2110,22 +2204,22 b' class ManifestCtx:'
2110 2204 # rev = store.rev(node)
2111 2205 # self.linkrev = store.linkrev(rev)
2112 2206
2113 def _storage(self):
2207 def _storage(self) -> 'ManifestRevlog':
2114 2208 return self._manifestlog.getstorage(b'')
2115 2209
2116 def node(self):
2210 def node(self) -> bytes:
2117 2211 return self._node
2118 2212
2119 def copy(self):
2213 def copy(self) -> MemManifestCtx:
2120 2214 memmf = memmanifestctx(self._manifestlog)
2121 2215 memmf._manifestdict = self.read().copy()
2122 2216 return memmf
2123 2217
2124 2218 @propertycache
2125 def parents(self):
2219 def parents(self) -> Tuple[bytes, bytes]:
2126 2220 return self._storage().parents(self._node)
2127 2221
2128 def read(self):
2222 def read(self) -> 'ManifestDict':
2129 2223 if self._data is None:
2130 2224 nc = self._manifestlog.nodeconstants
2131 2225 if self._node == nc.nullid:
@@ -2141,7 +2235,7 b' class ManifestCtx:'
2141 2235 self._data = manifestdict(nc.nodelen, text)
2142 2236 return self._data
2143 2237
2144 def readfast(self, shallow=False):
2238 def readfast(self, shallow: bool = False) -> 'ManifestDict':
2145 2239 """Calls either readdelta or read, based on which would be less work.
2146 2240 readdelta is called if the delta is against the p1, and therefore can be
2147 2241 read quickly.
@@ -2155,7 +2249,7 b' class ManifestCtx:'
2155 2249 return self.readdelta()
2156 2250 return self.read()
2157 2251
2158 def readdelta(self, shallow=False):
2252 def readdelta(self, shallow: bool = False) -> 'ManifestDict':
2159 2253 """Returns a manifest containing just the entries that are present
2160 2254 in this manifest, but not in its p1 manifest. This is efficient to read
2161 2255 if the revlog delta is already p1.
@@ -2167,7 +2261,7 b' class ManifestCtx:'
2167 2261 d = mdiff.patchtext(store.revdiff(store.deltaparent(r), r))
2168 2262 return manifestdict(store.nodeconstants.nodelen, d)
2169 2263
2170 def find(self, key):
2264 def find(self, key: bytes) -> Tuple[bytes, bytes]:
2171 2265 return self.read().find(key)
2172 2266
2173 2267
@@ -2182,15 +2276,15 b' class MemTreeManifestCtx:'
2182 2276 self._dir = dir
2183 2277 self._treemanifest = treemanifest(manifestlog.nodeconstants)
2184 2278
2185 def _storage(self):
2279 def _storage(self) -> ManifestRevlog:
2186 2280 return self._manifestlog.getstorage(b'')
2187 2281
2188 def copy(self):
2282 def copy(self) -> 'MemTreeManifestCtx':
2189 2283 memmf = memtreemanifestctx(self._manifestlog, dir=self._dir)
2190 2284 memmf._treemanifest = self._treemanifest.copy()
2191 2285 return memmf
2192 2286
2193 def read(self):
2287 def read(self) -> 'TreeManifest':
2194 2288 return self._treemanifest
2195 2289
2196 2290 def write(self, transaction, link, p1, p2, added, removed, match=None):
@@ -2230,7 +2324,7 b' class TreeManifestCtx:'
2230 2324 # rev = store.rev(node)
2231 2325 # self.linkrev = store.linkrev(rev)
2232 2326
2233 def _storage(self):
2327 def _storage(self) -> ManifestRevlog:
2234 2328 narrowmatch = self._manifestlog._narrowmatch
2235 2329 if not narrowmatch.always():
2236 2330 if not narrowmatch.visitdir(self._dir[:-1]):
@@ -2239,7 +2333,7 b' class TreeManifestCtx:'
2239 2333 )
2240 2334 return self._manifestlog.getstorage(self._dir)
2241 2335
2242 def read(self):
2336 def read(self) -> 'TreeManifest':
2243 2337 if self._data is None:
2244 2338 store = self._storage()
2245 2339 if self._node == self._manifestlog.nodeconstants.nullid:
@@ -2272,19 +2366,19 b' class TreeManifestCtx:'
2272 2366
2273 2367 return self._data
2274 2368
2275 def node(self):
2369 def node(self) -> bytes:
2276 2370 return self._node
2277 2371
2278 def copy(self):
2372 def copy(self) -> 'MemTreeManifestCtx':
2279 2373 memmf = memtreemanifestctx(self._manifestlog, dir=self._dir)
2280 2374 memmf._treemanifest = self.read().copy()
2281 2375 return memmf
2282 2376
2283 2377 @propertycache
2284 def parents(self):
2378 def parents(self) -> Tuple[bytes, bytes]:
2285 2379 return self._storage().parents(self._node)
2286 2380
2287 def readdelta(self, shallow=False):
2381 def readdelta(self, shallow: bool = False) -> AnyManifestDict:
2288 2382 """Returns a manifest containing just the entries that are present
2289 2383 in this manifest, but not in its p1 manifest. This is efficient to read
2290 2384 if the revlog delta is already p1.
@@ -2313,7 +2407,7 b' class TreeManifestCtx:'
2313 2407 md.setflag(f, fl1)
2314 2408 return md
2315 2409
2316 def readfast(self, shallow=False):
2410 def readfast(self, shallow=False) -> AnyManifestDict:
2317 2411 """Calls either readdelta or read, based on which would be less work.
2318 2412 readdelta is called if the delta is against the p1, and therefore can be
2319 2413 read quickly.
@@ -2334,7 +2428,7 b' class TreeManifestCtx:'
2334 2428 else:
2335 2429 return self.read()
2336 2430
2337 def find(self, key):
2431 def find(self, key: bytes) -> Tuple[bytes, bytes]:
2338 2432 return self.read().find(key)
2339 2433
2340 2434
General Comments 0
You need to be logged in to leave comments. Login now