Mercurial > public > mercurial-scm > hg
comparison mercurial/posix.py @ 52364:7ac7d5f20cb0
posix: (mostly) stop using the `pycompat.open()` shim
We still need it for the `posixfile` alias, because fixing all of those callers
is outside of the scope of this, and spills into the Windows implementation of
`posixfile`. But the other direct uses of `open()` can be dropped.
author | Matt Harbison <matt_harbison@yahoo.com> |
---|---|
date | Wed, 04 Dec 2024 20:52:05 -0500 |
parents | f4733654f144 |
children | dd052842fc8e |
comparison
equal
deleted
inserted
replaced
52363:6a8edf9f0a6d | 52364:7ac7d5f20cb0 |
---|---|
35 Tuple, | 35 Tuple, |
36 Union, | 36 Union, |
37 ) | 37 ) |
38 | 38 |
39 from .i18n import _ | 39 from .i18n import _ |
40 from .pycompat import ( | |
41 open, | |
42 ) | |
43 from . import ( | 40 from . import ( |
44 encoding, | 41 encoding, |
45 error, | 42 error, |
46 policy, | 43 policy, |
47 pycompat, | 44 pycompat, |
98 expandglobs: bool = False | 95 expandglobs: bool = False |
99 | 96 |
100 umask: int = os.umask(0) | 97 umask: int = os.umask(0) |
101 os.umask(umask) | 98 os.umask(umask) |
102 | 99 |
103 posixfile = open | 100 posixfile = pycompat.open |
104 | 101 |
105 | 102 |
106 def split(p: bytes) -> Tuple[bytes, bytes]: | 103 def split(p: bytes) -> Tuple[bytes, bytes]: |
107 """Same as posixpath.split, but faster | 104 """Same as posixpath.split, but faster |
108 | 105 |
172 st = os.lstat(f) | 169 st = os.lstat(f) |
173 s = st.st_mode | 170 s = st.st_mode |
174 if l: | 171 if l: |
175 if not stat.S_ISLNK(s): | 172 if not stat.S_ISLNK(s): |
176 # switch file to link | 173 # switch file to link |
177 with open(f, b'rb') as fp: | 174 with open(f, 'rb') as fp: |
178 data = fp.read() | 175 data = fp.read() |
179 unlink(f) | 176 unlink(f) |
180 try: | 177 try: |
181 os.symlink(data, f) | 178 os.symlink(data, f) |
182 except OSError: | 179 except OSError: |
183 # failed to make a link, rewrite file | 180 # failed to make a link, rewrite file |
184 with open(f, b"wb") as fp: | 181 with open(f, "wb") as fp: |
185 fp.write(data) | 182 fp.write(data) |
186 | 183 |
187 # no chmod needed at this point | 184 # no chmod needed at this point |
188 return | 185 return |
189 if stat.S_ISLNK(s): | 186 if stat.S_ISLNK(s): |
190 # switch link to file | 187 # switch link to file |
191 data = os.readlink(f) | 188 data = os.readlink(f) |
192 unlink(f) | 189 unlink(f) |
193 with open(f, b"wb") as fp: | 190 with open(f, "wb") as fp: |
194 fp.write(data) | 191 fp.write(data) |
195 s = 0o666 & ~umask # avoid restatting for chmod | 192 s = 0o666 & ~umask # avoid restatting for chmod |
196 | 193 |
197 sx = s & 0o100 | 194 sx = s & 0o100 |
198 if st.st_nlink > 1 and bool(x) != bool(sx): | 195 if st.st_nlink > 1 and bool(x) != bool(sx): |
199 # the file is a hardlink, break it | 196 # the file is a hardlink, break it |
200 with open(f, b"rb") as fp: | 197 with open(f, "rb") as fp: |
201 data = fp.read() | 198 data = fp.read() |
202 unlink(f) | 199 unlink(f) |
203 with open(f, b"wb") as fp: | 200 with open(f, "wb") as fp: |
204 fp.write(data) | 201 fp.write(data) |
205 | 202 |
206 if x and not sx: | 203 if x and not sx: |
207 # Turn on +x for every +r bit when making a file executable | 204 # Turn on +x for every +r bit when making a file executable |
208 # and obey umask. | 205 # and obey umask. |
280 if m & EXECFLAGS != 0: | 277 if m & EXECFLAGS != 0: |
281 # ensure checknoexec exists, check it isn't exec | 278 # ensure checknoexec exists, check it isn't exec |
282 try: | 279 try: |
283 m = os.stat(checknoexec).st_mode | 280 m = os.stat(checknoexec).st_mode |
284 except FileNotFoundError: | 281 except FileNotFoundError: |
285 open(checknoexec, b'w').close() # might fail | 282 open(checknoexec, 'w').close() # might fail |
286 m = os.stat(checknoexec).st_mode | 283 m = os.stat(checknoexec).st_mode |
287 if m & EXECFLAGS == 0: | 284 if m & EXECFLAGS == 0: |
288 # check-exec is exec and check-no-exec is not exec | 285 # check-exec is exec and check-no-exec is not exec |
289 return True | 286 return True |
290 # checknoexec exists but is exec - delete it | 287 # checknoexec exists but is exec - delete it |
347 # create a fixed file to link to; doesn't matter if it | 344 # create a fixed file to link to; doesn't matter if it |
348 # already exists. | 345 # already exists. |
349 target = b'checklink-target' | 346 target = b'checklink-target' |
350 try: | 347 try: |
351 fullpath = os.path.join(cachedir, target) | 348 fullpath = os.path.join(cachedir, target) |
352 open(fullpath, b'w').close() | 349 open(fullpath, 'w').close() |
353 except PermissionError: | 350 except PermissionError: |
354 # If we can't write to cachedir, just pretend | 351 # If we can't write to cachedir, just pretend |
355 # that the fs is readonly and by association | 352 # that the fs is readonly and by association |
356 # that the fs won't support symlinks. This | 353 # that the fs won't support symlinks. This |
357 # seems like the least dangerous way to avoid | 354 # seems like the least dangerous way to avoid |