Mercurial > public > mercurial-scm > hg-stable
comparison mercurial/util.py @ 51924:1d95a87813ad
typing: add type annotations to the `mercurial.util.filestat` class
It's referenced in the `vfs` classes, so get this out of the way to help there.
The `TypeVar` definition and its usage was copied from the existing `util.pyi`
file.
author | Matt Harbison <matt_harbison@yahoo.com> |
---|---|
date | Fri, 20 Sep 2024 00:04:09 -0400 |
parents | 8f3cbea2547c |
children | f833ad92ee44 |
comparison
equal
deleted
inserted
replaced
51923:e59e1d8d29d2 | 51924:1d95a87813ad |
---|---|
43 Iterable, | 43 Iterable, |
44 Iterator, | 44 Iterator, |
45 List, | 45 List, |
46 Optional, | 46 Optional, |
47 Tuple, | 47 Tuple, |
48 Type, | |
49 TypeVar, | |
48 ) | 50 ) |
49 | 51 |
50 from .node import hex | 52 from .node import hex |
51 from .thirdparty import attr | 53 from .thirdparty import attr |
52 | 54 |
155 statisexec = platform.statisexec | 157 statisexec = platform.statisexec |
156 statislink = platform.statislink | 158 statislink = platform.statislink |
157 umask = platform.umask | 159 umask = platform.umask |
158 unlink = platform.unlink | 160 unlink = platform.unlink |
159 username = platform.username | 161 username = platform.username |
162 | |
163 | |
164 if typing.TYPE_CHECKING: | |
165 _Tfilestat = TypeVar('_Tfilestat', bound='filestat') | |
160 | 166 |
161 | 167 |
162 def setumask(val: int) -> None: | 168 def setumask(val: int) -> None: |
163 '''updates the umask. used by chg server''' | 169 '''updates the umask. used by chg server''' |
164 if pycompat.iswindows: | 170 if pycompat.iswindows: |
2489 'stat' attribute is result of 'os.stat()' if specified 'path' | 2495 'stat' attribute is result of 'os.stat()' if specified 'path' |
2490 exists. Otherwise, it is None. This can avoid preparative | 2496 exists. Otherwise, it is None. This can avoid preparative |
2491 'exists()' examination on client side of this class. | 2497 'exists()' examination on client side of this class. |
2492 """ | 2498 """ |
2493 | 2499 |
2494 def __init__(self, stat): | 2500 def __init__(self, stat: Optional[os.stat_result]) -> None: |
2495 self.stat = stat | 2501 self.stat = stat |
2496 | 2502 |
2497 @classmethod | 2503 @classmethod |
2498 def frompath(cls, path): | 2504 def frompath(cls: Type[_Tfilestat], path: bytes) -> _Tfilestat: |
2499 try: | 2505 try: |
2500 stat = os.stat(path) | 2506 stat = os.stat(path) |
2501 except FileNotFoundError: | 2507 except FileNotFoundError: |
2502 stat = None | 2508 stat = None |
2503 return cls(stat) | 2509 return cls(stat) |
2504 | 2510 |
2505 @classmethod | 2511 @classmethod |
2506 def fromfp(cls, fp): | 2512 def fromfp(cls: Type[_Tfilestat], fp: BinaryIO) -> _Tfilestat: |
2507 stat = os.fstat(fp.fileno()) | 2513 stat = os.fstat(fp.fileno()) |
2508 return cls(stat) | 2514 return cls(stat) |
2509 | 2515 |
2510 __hash__ = object.__hash__ | 2516 __hash__ = object.__hash__ |
2511 | 2517 |
2512 def __eq__(self, old): | 2518 def __eq__(self, old) -> bool: |
2513 try: | 2519 try: |
2514 # if ambiguity between stat of new and old file is | 2520 # if ambiguity between stat of new and old file is |
2515 # avoided, comparison of size, ctime and mtime is enough | 2521 # avoided, comparison of size, ctime and mtime is enough |
2516 # to exactly detect change of a file regardless of platform | 2522 # to exactly detect change of a file regardless of platform |
2517 return ( | 2523 return ( |
2524 try: | 2530 try: |
2525 return self.stat is None and old.stat is None | 2531 return self.stat is None and old.stat is None |
2526 except AttributeError: | 2532 except AttributeError: |
2527 return False | 2533 return False |
2528 | 2534 |
2529 def isambig(self, old): | 2535 def isambig(self, old: _Tfilestat) -> bool: |
2530 """Examine whether new (= self) stat is ambiguous against old one | 2536 """Examine whether new (= self) stat is ambiguous against old one |
2531 | 2537 |
2532 "S[N]" below means stat of a file at N-th change: | 2538 "S[N]" below means stat of a file at N-th change: |
2533 | 2539 |
2534 - S[n-1].ctime < S[n].ctime: can detect change of a file | 2540 - S[n-1].ctime < S[n].ctime: can detect change of a file |
2559 try: | 2565 try: |
2560 return self.stat[stat.ST_CTIME] == old.stat[stat.ST_CTIME] | 2566 return self.stat[stat.ST_CTIME] == old.stat[stat.ST_CTIME] |
2561 except AttributeError: | 2567 except AttributeError: |
2562 return False | 2568 return False |
2563 | 2569 |
2564 def avoidambig(self, path, old): | 2570 def avoidambig(self, path: bytes, old: _Tfilestat) -> bool: |
2565 """Change file stat of specified path to avoid ambiguity | 2571 """Change file stat of specified path to avoid ambiguity |
2566 | 2572 |
2567 'old' should be previous filestat of 'path'. | 2573 'old' should be previous filestat of 'path'. |
2568 | 2574 |
2569 This skips avoiding ambiguity, if a process doesn't have | 2575 This skips avoiding ambiguity, if a process doesn't have |
2579 # utime() on the file created by another user causes EPERM, | 2585 # utime() on the file created by another user causes EPERM, |
2580 # if a process doesn't have appropriate privileges | 2586 # if a process doesn't have appropriate privileges |
2581 return False | 2587 return False |
2582 return True | 2588 return True |
2583 | 2589 |
2584 def __ne__(self, other): | 2590 def __ne__(self, other) -> bool: |
2585 return not self == other | 2591 return not self == other |
2586 | 2592 |
2587 | 2593 |
2588 class atomictempfile: | 2594 class atomictempfile: |
2589 """writable file object that atomically updates a file | 2595 """writable file object that atomically updates a file |