Mercurial > public > mercurial-scm > hg-stable
comparison mercurial/pathutil.py @ 43076:2372284d9457
formatting: blacken the codebase
This is using my patch to black
(https://github.com/psf/black/pull/826) so we don't un-wrap collection
literals.
Done with:
hg files 'set:**.py - mercurial/thirdparty/** - "contrib/python-zstandard/**"' | xargs black -S
# skip-blame mass-reformatting only
# no-check-commit reformats foo_bar functions
Differential Revision: https://phab.mercurial-scm.org/D6971
author | Augie Fackler <augie@google.com> |
---|---|
date | Sun, 06 Oct 2019 09:45:02 -0400 |
parents | 21be76e07148 |
children | 687b865b95ad |
comparison
equal
deleted
inserted
replaced
43075:57875cf423c9 | 43076:2372284d9457 |
---|---|
11 error, | 11 error, |
12 pycompat, | 12 pycompat, |
13 util, | 13 util, |
14 ) | 14 ) |
15 | 15 |
16 | |
16 def _lowerclean(s): | 17 def _lowerclean(s): |
17 return encoding.hfsignoreclean(s.lower()) | 18 return encoding.hfsignoreclean(s.lower()) |
19 | |
18 | 20 |
19 class pathauditor(object): | 21 class pathauditor(object): |
20 '''ensure that a filesystem path contains no banned components. | 22 '''ensure that a filesystem path contains no banned components. |
21 the following properties of a path are checked: | 23 the following properties of a path are checked: |
22 | 24 |
61 return | 63 return |
62 # AIX ignores "/" at end of path, others raise EISDIR. | 64 # AIX ignores "/" at end of path, others raise EISDIR. |
63 if util.endswithsep(path): | 65 if util.endswithsep(path): |
64 raise error.Abort(_("path ends in directory separator: %s") % path) | 66 raise error.Abort(_("path ends in directory separator: %s") % path) |
65 parts = util.splitpath(path) | 67 parts = util.splitpath(path) |
66 if (os.path.splitdrive(path)[0] | 68 if ( |
69 os.path.splitdrive(path)[0] | |
67 or _lowerclean(parts[0]) in ('.hg', '.hg.', '') | 70 or _lowerclean(parts[0]) in ('.hg', '.hg.', '') |
68 or pycompat.ospardir in parts): | 71 or pycompat.ospardir in parts |
72 ): | |
69 raise error.Abort(_("path contains illegal component: %s") % path) | 73 raise error.Abort(_("path contains illegal component: %s") % path) |
70 # Windows shortname aliases | 74 # Windows shortname aliases |
71 for p in parts: | 75 for p in parts: |
72 if "~" in p: | 76 if "~" in p: |
73 first, last = p.split("~", 1) | 77 first, last = p.split("~", 1) |
74 if last.isdigit() and first.upper() in ["HG", "HG8B6C"]: | 78 if last.isdigit() and first.upper() in ["HG", "HG8B6C"]: |
75 raise error.Abort(_("path contains illegal component: %s") | 79 raise error.Abort( |
76 % path) | 80 _("path contains illegal component: %s") % path |
81 ) | |
77 if '.hg' in _lowerclean(path): | 82 if '.hg' in _lowerclean(path): |
78 lparts = [_lowerclean(p.lower()) for p in parts] | 83 lparts = [_lowerclean(p.lower()) for p in parts] |
79 for p in '.hg', '.hg.': | 84 for p in '.hg', '.hg.': |
80 if p in lparts[1:]: | 85 if p in lparts[1:]: |
81 pos = lparts.index(p) | 86 pos = lparts.index(p) |
82 base = os.path.join(*parts[:pos]) | 87 base = os.path.join(*parts[:pos]) |
83 raise error.Abort(_("path '%s' is inside nested repo %r") | 88 raise error.Abort( |
84 % (path, pycompat.bytestr(base))) | 89 _("path '%s' is inside nested repo %r") |
90 % (path, pycompat.bytestr(base)) | |
91 ) | |
85 | 92 |
86 normparts = util.splitpath(normpath) | 93 normparts = util.splitpath(normpath) |
87 assert len(parts) == len(normparts) | 94 assert len(parts) == len(normparts) |
88 | 95 |
89 parts.pop() | 96 parts.pop() |
91 prefixes = [] | 98 prefixes = [] |
92 # It's important that we check the path parts starting from the root. | 99 # It's important that we check the path parts starting from the root. |
93 # This means we won't accidentally traverse a symlink into some other | 100 # This means we won't accidentally traverse a symlink into some other |
94 # filesystem (which is potentially expensive to access). | 101 # filesystem (which is potentially expensive to access). |
95 for i in range(len(parts)): | 102 for i in range(len(parts)): |
96 prefix = pycompat.ossep.join(parts[:i + 1]) | 103 prefix = pycompat.ossep.join(parts[: i + 1]) |
97 normprefix = pycompat.ossep.join(normparts[:i + 1]) | 104 normprefix = pycompat.ossep.join(normparts[: i + 1]) |
98 if normprefix in self.auditeddir: | 105 if normprefix in self.auditeddir: |
99 continue | 106 continue |
100 if self._realfs: | 107 if self._realfs: |
101 self._checkfs(prefix, path) | 108 self._checkfs(prefix, path) |
102 prefixes.append(normprefix) | 109 prefixes.append(normprefix) |
117 # They must be ignored for patterns can be checked too. | 124 # They must be ignored for patterns can be checked too. |
118 if err.errno not in (errno.ENOENT, errno.ENOTDIR, errno.EINVAL): | 125 if err.errno not in (errno.ENOENT, errno.ENOTDIR, errno.EINVAL): |
119 raise | 126 raise |
120 else: | 127 else: |
121 if stat.S_ISLNK(st.st_mode): | 128 if stat.S_ISLNK(st.st_mode): |
122 msg = (_('path %r traverses symbolic link %r') | 129 msg = _('path %r traverses symbolic link %r') % ( |
123 % (pycompat.bytestr(path), pycompat.bytestr(prefix))) | 130 pycompat.bytestr(path), |
131 pycompat.bytestr(prefix), | |
132 ) | |
124 raise error.Abort(msg) | 133 raise error.Abort(msg) |
125 elif (stat.S_ISDIR(st.st_mode) and | 134 elif stat.S_ISDIR(st.st_mode) and os.path.isdir( |
126 os.path.isdir(os.path.join(curpath, '.hg'))): | 135 os.path.join(curpath, '.hg') |
136 ): | |
127 if not self.callback or not self.callback(curpath): | 137 if not self.callback or not self.callback(curpath): |
128 msg = _("path '%s' is inside nested repo %r") | 138 msg = _("path '%s' is inside nested repo %r") |
129 raise error.Abort(msg % (path, pycompat.bytestr(prefix))) | 139 raise error.Abort(msg % (path, pycompat.bytestr(prefix))) |
130 | 140 |
131 def check(self, path): | 141 def check(self, path): |
132 try: | 142 try: |
133 self(path) | 143 self(path) |
134 return True | 144 return True |
135 except (OSError, error.Abort): | 145 except (OSError, error.Abort): |
136 return False | 146 return False |
147 | |
137 | 148 |
138 def canonpath(root, cwd, myname, auditor=None): | 149 def canonpath(root, cwd, myname, auditor=None): |
139 '''return the canonical path of myname, given cwd and root | 150 '''return the canonical path of myname, given cwd and root |
140 | 151 |
141 >>> def check(root, cwd, myname): | 152 >>> def check(root, cwd, myname): |
186 name = os.path.join(root, cwd, name) | 197 name = os.path.join(root, cwd, name) |
187 name = os.path.normpath(name) | 198 name = os.path.normpath(name) |
188 if auditor is None: | 199 if auditor is None: |
189 auditor = pathauditor(root) | 200 auditor = pathauditor(root) |
190 if name != rootsep and name.startswith(rootsep): | 201 if name != rootsep and name.startswith(rootsep): |
191 name = name[len(rootsep):] | 202 name = name[len(rootsep) :] |
192 auditor(name) | 203 auditor(name) |
193 return util.pconvert(name) | 204 return util.pconvert(name) |
194 elif name == root: | 205 elif name == root: |
195 return '' | 206 return '' |
196 else: | 207 else: |
226 if cwd != root: | 237 if cwd != root: |
227 canonpath(root, root, myname, auditor) | 238 canonpath(root, root, myname, auditor) |
228 relpath = util.pathto(root, cwd, '') | 239 relpath = util.pathto(root, cwd, '') |
229 if relpath.endswith(pycompat.ossep): | 240 if relpath.endswith(pycompat.ossep): |
230 relpath = relpath[:-1] | 241 relpath = relpath[:-1] |
231 hint = (_("consider using '--cwd %s'") % relpath) | 242 hint = _("consider using '--cwd %s'") % relpath |
232 except error.Abort: | 243 except error.Abort: |
233 pass | 244 pass |
234 | 245 |
235 raise error.Abort(_("%s not under root '%s'") % (myname, root), | 246 raise error.Abort( |
236 hint=hint) | 247 _("%s not under root '%s'") % (myname, root), hint=hint |
248 ) | |
249 | |
237 | 250 |
238 def normasprefix(path): | 251 def normasprefix(path): |
239 '''normalize the specified path as path prefix | 252 '''normalize the specified path as path prefix |
240 | 253 |
241 Returned value can be used safely for "p.startswith(prefix)", | 254 Returned value can be used safely for "p.startswith(prefix)", |
255 if len(p) != len(pycompat.ossep): | 268 if len(p) != len(pycompat.ossep): |
256 return path + pycompat.ossep | 269 return path + pycompat.ossep |
257 else: | 270 else: |
258 return path | 271 return path |
259 | 272 |
273 | |
260 # forward two methods from posixpath that do what we need, but we'd | 274 # forward two methods from posixpath that do what we need, but we'd |
261 # rather not let our internals know that we're thinking in posix terms | 275 # rather not let our internals know that we're thinking in posix terms |
262 # - instead we'll let them be oblivious. | 276 # - instead we'll let them be oblivious. |
263 join = posixpath.join | 277 join = posixpath.join |
264 dirname = posixpath.dirname | 278 dirname = posixpath.dirname |