equal
deleted
inserted
replaced
145 umask = platform.umask |
145 umask = platform.umask |
146 unlink = platform.unlink |
146 unlink = platform.unlink |
147 username = platform.username |
147 username = platform.username |
148 |
148 |
149 |
149 |
150 def setumask(val): |
150 def setumask(val: int) -> None: |
151 # type: (int) -> None |
|
152 '''updates the umask. used by chg server''' |
151 '''updates the umask. used by chg server''' |
153 if pycompat.iswindows: |
152 if pycompat.iswindows: |
154 return |
153 return |
155 os.umask(val) |
154 os.umask(val) |
156 global umask |
155 global umask |
1848 if pycompat.ispypy: |
1847 if pycompat.ispypy: |
1849 # PyPy runs slower with gc disabled |
1848 # PyPy runs slower with gc disabled |
1850 nogc = lambda x: x |
1849 nogc = lambda x: x |
1851 |
1850 |
1852 |
1851 |
1853 def pathto(root, n1, n2): |
1852 def pathto(root: bytes, n1: bytes, n2: bytes) -> bytes: |
1854 # type: (bytes, bytes, bytes) -> bytes |
|
1855 """return the relative path from one place to another. |
1853 """return the relative path from one place to another. |
1856 root should use os.sep to separate directories |
1854 root should use os.sep to separate directories |
1857 n1 should use os.sep to separate directories |
1855 n1 should use os.sep to separate directories |
1858 n2 should use "/" to separate directories |
1856 n2 should use "/" to separate directories |
1859 returns an os.sep-separated path. |
1857 returns an os.sep-separated path. |
2060 b'lpt9', |
2058 b'lpt9', |
2061 } |
2059 } |
2062 _winreservedchars = b':*?"<>|' |
2060 _winreservedchars = b':*?"<>|' |
2063 |
2061 |
2064 |
2062 |
2065 def checkwinfilename(path): |
2063 def checkwinfilename(path: bytes) -> Optional[bytes]: |
2066 # type: (bytes) -> Optional[bytes] |
|
2067 r"""Check that the base-relative path is a valid filename on Windows. |
2064 r"""Check that the base-relative path is a valid filename on Windows. |
2068 Returns None if the path is ok, or a UI string describing the problem. |
2065 Returns None if the path is ok, or a UI string describing the problem. |
2069 |
2066 |
2070 >>> checkwinfilename(b"just/a/normal/path") |
2067 >>> checkwinfilename(b"just/a/normal/path") |
2071 >>> checkwinfilename(b"foo/bar/con.xml") |
2068 >>> checkwinfilename(b"foo/bar/con.xml") |
2155 ld = os.open(pathname, flags) |
2152 ld = os.open(pathname, flags) |
2156 os.write(ld, info) |
2153 os.write(ld, info) |
2157 os.close(ld) |
2154 os.close(ld) |
2158 |
2155 |
2159 |
2156 |
2160 def readlock(pathname): |
2157 def readlock(pathname: bytes) -> bytes: |
2161 # type: (bytes) -> bytes |
|
2162 try: |
2158 try: |
2163 return readlink(pathname) |
2159 return readlink(pathname) |
2164 except OSError as why: |
2160 except OSError as why: |
2165 if why.errno not in (errno.EINVAL, errno.ENOSYS): |
2161 if why.errno not in (errno.EINVAL, errno.ENOSYS): |
2166 raise |
2162 raise |
2179 |
2175 |
2180 |
2176 |
2181 # File system features |
2177 # File system features |
2182 |
2178 |
2183 |
2179 |
2184 def fscasesensitive(path): |
2180 def fscasesensitive(path: bytes) -> bool: |
2185 # type: (bytes) -> bool |
|
2186 """ |
2181 """ |
2187 Return true if the given path is on a case-sensitive filesystem |
2182 Return true if the given path is on a case-sensitive filesystem |
2188 |
2183 |
2189 Requires a path (like /foo/.hg) ending with a foldable final |
2184 Requires a path (like /foo/.hg) ending with a foldable final |
2190 directory component. |
2185 directory component. |
2284 re = _re() |
2279 re = _re() |
2285 |
2280 |
2286 _fspathcache = {} |
2281 _fspathcache = {} |
2287 |
2282 |
2288 |
2283 |
2289 def fspath(name, root): |
2284 def fspath(name: bytes, root: bytes) -> bytes: |
2290 # type: (bytes, bytes) -> bytes |
|
2291 """Get name in the case stored in the filesystem |
2285 """Get name in the case stored in the filesystem |
2292 |
2286 |
2293 The name should be relative to root, and be normcase-ed for efficiency. |
2287 The name should be relative to root, and be normcase-ed for efficiency. |
2294 |
2288 |
2295 Note that this function is unnecessary, and should not be |
2289 Note that this function is unnecessary, and should not be |
2329 dir = os.path.join(dir, part) |
2323 dir = os.path.join(dir, part) |
2330 |
2324 |
2331 return b''.join(result) |
2325 return b''.join(result) |
2332 |
2326 |
2333 |
2327 |
2334 def checknlink(testfile): |
2328 def checknlink(testfile: bytes) -> bool: |
2335 # type: (bytes) -> bool |
|
2336 '''check whether hardlink count reporting works properly''' |
2329 '''check whether hardlink count reporting works properly''' |
2337 |
2330 |
2338 # testfile may be open, so we need a separate file for checking to |
2331 # testfile may be open, so we need a separate file for checking to |
2339 # work around issue2543 (or testfile may get lost on Samba shares) |
2332 # work around issue2543 (or testfile may get lost on Samba shares) |
2340 f1, f2, fp = None, None, None |
2333 f1, f2, fp = None, None, None |
2363 os.unlink(f) |
2356 os.unlink(f) |
2364 except OSError: |
2357 except OSError: |
2365 pass |
2358 pass |
2366 |
2359 |
2367 |
2360 |
2368 def endswithsep(path): |
2361 def endswithsep(path: bytes) -> bool: |
2369 # type: (bytes) -> bool |
|
2370 '''Check path ends with os.sep or os.altsep.''' |
2362 '''Check path ends with os.sep or os.altsep.''' |
2371 return bool( # help pytype |
2363 return bool( # help pytype |
2372 path.endswith(pycompat.ossep) |
2364 path.endswith(pycompat.ossep) |
2373 or pycompat.osaltsep |
2365 or pycompat.osaltsep |
2374 and path.endswith(pycompat.osaltsep) |
2366 and path.endswith(pycompat.osaltsep) |
2375 ) |
2367 ) |
2376 |
2368 |
2377 |
2369 |
2378 def splitpath(path): |
2370 def splitpath(path: bytes) -> List[bytes]: |
2379 # type: (bytes) -> List[bytes] |
|
2380 """Split path by os.sep. |
2371 """Split path by os.sep. |
2381 Note that this function does not use os.altsep because this is |
2372 Note that this function does not use os.altsep because this is |
2382 an alternative of simple "xxx.split(os.sep)". |
2373 an alternative of simple "xxx.split(os.sep)". |
2383 It is recommended to use os.path.normpath() before using this |
2374 It is recommended to use os.path.normpath() before using this |
2384 function if need.""" |
2375 function if need.""" |
2607 except OSError as e: |
2598 except OSError as e: |
2608 if e.errno != errno.ENOENT and e.errno != errno.ENOTEMPTY: |
2599 if e.errno != errno.ENOENT and e.errno != errno.ENOTEMPTY: |
2609 raise |
2600 raise |
2610 |
2601 |
2611 |
2602 |
2612 def unlinkpath(f, ignoremissing=False, rmdir=True): |
2603 def unlinkpath( |
2613 # type: (bytes, bool, bool) -> None |
2604 f: bytes, ignoremissing: bool = False, rmdir: bool = True |
|
2605 ) -> None: |
2614 """unlink and remove the directory if it is empty""" |
2606 """unlink and remove the directory if it is empty""" |
2615 if ignoremissing: |
2607 if ignoremissing: |
2616 tryunlink(f) |
2608 tryunlink(f) |
2617 else: |
2609 else: |
2618 unlink(f) |
2610 unlink(f) |
2622 removedirs(os.path.dirname(f)) |
2614 removedirs(os.path.dirname(f)) |
2623 except OSError: |
2615 except OSError: |
2624 pass |
2616 pass |
2625 |
2617 |
2626 |
2618 |
2627 def tryunlink(f): |
2619 def tryunlink(f: bytes) -> None: |
2628 # type: (bytes) -> None |
|
2629 """Attempt to remove a file, ignoring FileNotFoundError.""" |
2620 """Attempt to remove a file, ignoring FileNotFoundError.""" |
2630 try: |
2621 try: |
2631 unlink(f) |
2622 unlink(f) |
2632 except FileNotFoundError: |
2623 except FileNotFoundError: |
2633 pass |
2624 pass |
2634 |
2625 |
2635 |
2626 |
2636 def makedirs(name, mode=None, notindexed=False): |
2627 def makedirs( |
2637 # type: (bytes, Optional[int], bool) -> None |
2628 name: bytes, mode: Optional[int] = None, notindexed: bool = False |
|
2629 ) -> None: |
2638 """recursive directory creation with parent mode inheritance |
2630 """recursive directory creation with parent mode inheritance |
2639 |
2631 |
2640 Newly created directories are marked as "not to be indexed by |
2632 Newly created directories are marked as "not to be indexed by |
2641 the content indexing service", if ``notindexed`` is specified |
2633 the content indexing service", if ``notindexed`` is specified |
2642 for "write" mode access. |
2634 for "write" mode access. |
2661 raise |
2653 raise |
2662 if mode is not None: |
2654 if mode is not None: |
2663 os.chmod(name, mode) |
2655 os.chmod(name, mode) |
2664 |
2656 |
2665 |
2657 |
2666 def readfile(path): |
2658 def readfile(path: bytes) -> bytes: |
2667 # type: (bytes) -> bytes |
|
2668 with open(path, b'rb') as fp: |
2659 with open(path, b'rb') as fp: |
2669 return fp.read() |
2660 return fp.read() |
2670 |
2661 |
2671 |
2662 |
2672 def writefile(path, text): |
2663 def writefile(path: bytes, text: bytes) -> None: |
2673 # type: (bytes, bytes) -> None |
|
2674 with open(path, b'wb') as fp: |
2664 with open(path, b'wb') as fp: |
2675 fp.write(text) |
2665 fp.write(text) |
2676 |
2666 |
2677 |
2667 |
2678 def appendfile(path, text): |
2668 def appendfile(path: bytes, text: bytes) -> None: |
2679 # type: (bytes, bytes) -> None |
|
2680 with open(path, b'ab') as fp: |
2669 with open(path, b'ab') as fp: |
2681 fp.write(text) |
2670 fp.write(text) |
2682 |
2671 |
2683 |
2672 |
2684 class chunkbuffer: |
2673 class chunkbuffer: |
2835 return unittable[-1][2] % count |
2824 return unittable[-1][2] % count |
2836 |
2825 |
2837 return go |
2826 return go |
2838 |
2827 |
2839 |
2828 |
2840 def processlinerange(fromline, toline): |
2829 def processlinerange(fromline: int, toline: int) -> Tuple[int, int]: |
2841 # type: (int, int) -> Tuple[int, int] |
|
2842 """Check that linerange <fromline>:<toline> makes sense and return a |
2830 """Check that linerange <fromline>:<toline> makes sense and return a |
2843 0-based range. |
2831 0-based range. |
2844 |
2832 |
2845 >>> processlinerange(10, 20) |
2833 >>> processlinerange(10, 20) |
2846 (9, 20) |
2834 (9, 20) |
2895 # are removed or a LF. We do not care about old Macintosh files, so a |
2883 # are removed or a LF. We do not care about old Macintosh files, so a |
2896 # stray CR is an error. |
2884 # stray CR is an error. |
2897 _eolre = remod.compile(br'\r*\n') |
2885 _eolre = remod.compile(br'\r*\n') |
2898 |
2886 |
2899 |
2887 |
2900 def tolf(s): |
2888 def tolf(s: bytes) -> bytes: |
2901 # type: (bytes) -> bytes |
|
2902 return _eolre.sub(b'\n', s) |
2889 return _eolre.sub(b'\n', s) |
2903 |
2890 |
2904 |
2891 |
2905 def tocrlf(s): |
2892 def tocrlf(s: bytes) -> bytes: |
2906 # type: (bytes) -> bytes |
|
2907 return _eolre.sub(b'\r\n', s) |
2893 return _eolre.sub(b'\r\n', s) |
2908 |
2894 |
2909 |
2895 |
2910 def _crlfwriter(fp): |
2896 def _crlfwriter(fp): |
2911 return transformingwriter(fp, tocrlf) |
2897 return transformingwriter(fp, tocrlf) |
2924 # TODO delete since workaround variant for Python 2 no longer needed. |
2910 # TODO delete since workaround variant for Python 2 no longer needed. |
2925 def iterfile(fp): |
2911 def iterfile(fp): |
2926 return fp |
2912 return fp |
2927 |
2913 |
2928 |
2914 |
2929 def iterlines(iterator): |
2915 def iterlines(iterator: Iterable[bytes]) -> Iterator[bytes]: |
2930 # type: (Iterable[bytes]) -> Iterator[bytes] |
|
2931 for chunk in iterator: |
2916 for chunk in iterator: |
2932 for line in chunk.splitlines(): |
2917 for line in chunk.splitlines(): |
2933 yield line |
2918 yield line |
2934 |
2919 |
2935 |
2920 |
2936 def expandpath(path): |
2921 def expandpath(path: bytes) -> bytes: |
2937 # type: (bytes) -> bytes |
|
2938 return os.path.expanduser(os.path.expandvars(path)) |
2922 return os.path.expanduser(os.path.expandvars(path)) |
2939 |
2923 |
2940 |
2924 |
2941 def interpolate(prefix, mapping, s, fn=None, escape_prefix=False): |
2925 def interpolate(prefix, mapping, s, fn=None, escape_prefix=False): |
2942 """Return the result of interpolating items in the mapping into string s. |
2926 """Return the result of interpolating items in the mapping into string s. |
3060 (b'gb', 2 ** 30), |
3044 (b'gb', 2 ** 30), |
3061 (b'b', 1), |
3045 (b'b', 1), |
3062 ) |
3046 ) |
3063 |
3047 |
3064 |
3048 |
3065 def sizetoint(s): |
3049 def sizetoint(s: bytes) -> int: |
3066 # type: (bytes) -> int |
|
3067 """Convert a space specifier to a byte count. |
3050 """Convert a space specifier to a byte count. |
3068 |
3051 |
3069 >>> sizetoint(b'30') |
3052 >>> sizetoint(b'30') |
3070 30 |
3053 30 |
3071 >>> sizetoint(b'2.2kb') |
3054 >>> sizetoint(b'2.2kb') |
3283 locale.setlocale(locale.LC_CTYPE, oldloc) |
3266 locale.setlocale(locale.LC_CTYPE, oldloc) |
3284 else: |
3267 else: |
3285 yield |
3268 yield |
3286 |
3269 |
3287 |
3270 |
3288 def _estimatememory(): |
3271 def _estimatememory() -> Optional[int]: |
3289 # type: () -> Optional[int] |
|
3290 """Provide an estimate for the available system memory in Bytes. |
3272 """Provide an estimate for the available system memory in Bytes. |
3291 |
3273 |
3292 If no estimate can be provided on the platform, returns None. |
3274 If no estimate can be provided on the platform, returns None. |
3293 """ |
3275 """ |
3294 if pycompat.sysplatform.startswith(b'win'): |
3276 if pycompat.sysplatform.startswith(b'win'): |