##// END OF EJS Templates
style: run a patched black on a subset of mercurial...
Augie Fackler -
r43345:57875cf4 default
parent child Browse files
Show More
@@ -10,7 +10,7 b' import sys'
10 10 # Import a minimal set of stdlib modules needed for list_stdlib_modules()
11 11 # to work when run from a virtualenv. The modules were chosen empirically
12 12 # so that the return value matches the return value without virtualenv.
13 if True: # disable lexical sorting checks
13 if True: # disable lexical sorting checks
14 14 try:
15 15 import BaseHTTPServer as basehttpserver
16 16 except ImportError:
@@ -47,9 +47,7 b' allowsymbolimports = ('
47 47 )
48 48
49 49 # Whitelist of symbols that can be directly imported.
50 directsymbols = (
51 'demandimport',
52 )
50 directsymbols = ('demandimport',)
53 51
54 52 # Modules that must be aliased because they are commonly confused with
55 53 # common variables and can create aliasing and readability issues.
@@ -57,6 +55,7 b' requirealias = {'
57 55 'ui': 'uimod',
58 56 }
59 57
58
60 59 def usingabsolute(root):
61 60 """Whether absolute imports are being used."""
62 61 if sys.version_info[0] >= 3:
@@ -71,6 +70,7 b' def usingabsolute(root):'
71 70
72 71 return False
73 72
73
74 74 def walklocal(root):
75 75 """Recursively yield all descendant nodes but not in a different scope"""
76 76 todo = collections.deque(ast.iter_child_nodes(root))
@@ -82,6 +82,7 b' def walklocal(root):'
82 82 todo.extend(ast.iter_child_nodes(node))
83 83 yield node, newscope
84 84
85
85 86 def dotted_name_of_path(path):
86 87 """Given a relative path to a source file, return its dotted module name.
87 88
@@ -91,11 +92,12 b' def dotted_name_of_path(path):'
91 92 'zlib'
92 93 """
93 94 parts = path.replace(os.sep, '/').split('/')
94 parts[-1] = parts[-1].split('.', 1)[0] # remove .py and .so and .ARCH.so
95 parts[-1] = parts[-1].split('.', 1)[0] # remove .py and .so and .ARCH.so
95 96 if parts[-1].endswith('module'):
96 97 parts[-1] = parts[-1][:-6]
97 98 return '.'.join(parts)
98 99
100
99 101 def fromlocalfunc(modulename, localmods):
100 102 """Get a function to examine which locally defined module the
101 103 target source imports via a specified name.
@@ -164,6 +166,7 b' def fromlocalfunc(modulename, localmods)'
164 166 prefix = '.'.join(modulename.split('.')[:-1])
165 167 if prefix:
166 168 prefix += '.'
169
167 170 def fromlocal(name, level=0):
168 171 # name is false value when relative imports are used.
169 172 if not name:
@@ -175,8 +178,9 b' def fromlocalfunc(modulename, localmods)'
175 178 # Check relative name first.
176 179 candidates = [prefix + name, name]
177 180 else:
178 candidates = ['.'.join(modulename.split('.')[:-level]) +
179 '.' + name]
181 candidates = [
182 '.'.join(modulename.split('.')[:-level]) + '.' + name
183 ]
180 184
181 185 for n in candidates:
182 186 if n in localmods:
@@ -185,18 +189,21 b' def fromlocalfunc(modulename, localmods)'
185 189 if dottedpath in localmods:
186 190 return (n, dottedpath, True)
187 191 return False
192
188 193 return fromlocal
189 194
195
190 196 def populateextmods(localmods):
191 197 """Populate C extension modules based on pure modules"""
192 198 newlocalmods = set(localmods)
193 199 for n in localmods:
194 200 if n.startswith('mercurial.pure.'):
195 m = n[len('mercurial.pure.'):]
201 m = n[len('mercurial.pure.') :]
196 202 newlocalmods.add('mercurial.cext.' + m)
197 203 newlocalmods.add('mercurial.cffi._' + m)
198 204 return newlocalmods
199 205
206
200 207 def list_stdlib_modules():
201 208 """List the modules present in the stdlib.
202 209
@@ -232,13 +239,13 b' def list_stdlib_modules():'
232 239 for m in ['msvcrt', '_winreg']:
233 240 yield m
234 241 yield '__builtin__'
235 yield 'builtins' # python3 only
236 yield 'importlib.abc' # python3 only
237 yield 'importlib.machinery' # python3 only
238 yield 'importlib.util' # python3 only
242 yield 'builtins' # python3 only
243 yield 'importlib.abc' # python3 only
244 yield 'importlib.machinery' # python3 only
245 yield 'importlib.util' # python3 only
239 246 for m in 'fcntl', 'grp', 'pwd', 'termios': # Unix only
240 247 yield m
241 for m in 'cPickle', 'datetime': # in Python (not C) on PyPy
248 for m in 'cPickle', 'datetime': # in Python (not C) on PyPy
242 249 yield m
243 250 for m in ['cffi']:
244 251 yield m
@@ -264,14 +271,17 b' def list_stdlib_modules():'
264 271 for libpath in sys.path:
265 272 # We want to walk everything in sys.path that starts with something in
266 273 # stdlib_prefixes, but not directories from the hg sources.
267 if (os.path.abspath(libpath).startswith(sourceroot)
268 or not any(libpath.startswith(p) for p in stdlib_prefixes)):
274 if os.path.abspath(libpath).startswith(sourceroot) or not any(
275 libpath.startswith(p) for p in stdlib_prefixes
276 ):
269 277 continue
270 278 for top, dirs, files in os.walk(libpath):
271 279 for i, d in reversed(list(enumerate(dirs))):
272 if (not os.path.exists(os.path.join(top, d, '__init__.py'))
273 or top == libpath and d in ('hgdemandimport', 'hgext',
274 'mercurial')):
280 if (
281 not os.path.exists(os.path.join(top, d, '__init__.py'))
282 or top == libpath
283 and d in ('hgdemandimport', 'hgext', 'mercurial')
284 ):
275 285 del dirs[i]
276 286 for name in files:
277 287 if not name.endswith(('.py', '.so', '.pyc', '.pyo', '.pyd')):
@@ -280,12 +290,14 b' def list_stdlib_modules():'
280 290 full_path = top
281 291 else:
282 292 full_path = os.path.join(top, name)
283 rel_path = full_path[len(libpath) + 1:]
293 rel_path = full_path[len(libpath) + 1 :]
284 294 mod = dotted_name_of_path(rel_path)
285 295 yield mod
286 296
297
287 298 stdlib_modules = set(list_stdlib_modules())
288 299
300
289 301 def imported_modules(source, modulename, f, localmods, ignore_nested=False):
290 302 """Given the source of a file as a string, yield the names
291 303 imported by that file.
@@ -383,6 +395,7 b' def imported_modules(source, modulename,'
383 395 # lookup
384 396 yield dottedpath
385 397
398
386 399 def verify_import_convention(module, source, localmods):
387 400 """Verify imports match our established coding convention.
388 401
@@ -400,6 +413,7 b' def verify_import_convention(module, sou'
400 413 else:
401 414 return verify_stdlib_on_own_line(root)
402 415
416
403 417 def verify_modern_convention(module, root, localmods, root_col_offset=0):
404 418 """Verify a file conforms to the modern import convention rules.
405 419
@@ -443,19 +457,24 b' def verify_modern_convention(module, roo'
443 457 seenlevels = set()
444 458
445 459 for node, newscope in walklocal(root):
460
446 461 def msg(fmt, *args):
447 462 return (fmt % args, node.lineno)
463
448 464 if newscope:
449 465 # Check for local imports in function
450 for r in verify_modern_convention(module, node, localmods,
451 node.col_offset + 4):
466 for r in verify_modern_convention(
467 module, node, localmods, node.col_offset + 4
468 ):
452 469 yield r
453 470 elif isinstance(node, ast.Import):
454 471 # Disallow "import foo, bar" and require separate imports
455 472 # for each module.
456 473 if len(node.names) > 1:
457 yield msg('multiple imported names: %s',
458 ', '.join(n.name for n in node.names))
474 yield msg(
475 'multiple imported names: %s',
476 ', '.join(n.name for n in node.names),
477 )
459 478
460 479 name = node.names[0].name
461 480 asname = node.names[0].asname
@@ -465,16 +484,20 b' def verify_modern_convention(module, roo'
465 484 # Ignore sorting rules on imports inside blocks.
466 485 if node.col_offset == root_col_offset:
467 486 if lastname and name < lastname and laststdlib == stdlib:
468 yield msg('imports not lexically sorted: %s < %s',
469 name, lastname)
487 yield msg(
488 'imports not lexically sorted: %s < %s', name, lastname
489 )
470 490
471 491 lastname = name
472 492 laststdlib = stdlib
473 493
474 494 # stdlib imports should be before local imports.
475 495 if stdlib and seenlocal and node.col_offset == root_col_offset:
476 yield msg('stdlib import "%s" follows local import: %s',
477 name, seenlocal)
496 yield msg(
497 'stdlib import "%s" follows local import: %s',
498 name,
499 seenlocal,
500 )
478 501
479 502 if not stdlib:
480 503 seenlocal = name
@@ -485,13 +508,16 b' def verify_modern_convention(module, roo'
485 508 yield msg('import should be relative: %s', name)
486 509
487 510 if name in requirealias and asname != requirealias[name]:
488 yield msg('%s module must be "as" aliased to %s',
489 name, requirealias[name])
511 yield msg(
512 '%s module must be "as" aliased to %s',
513 name,
514 requirealias[name],
515 )
490 516
491 517 elif isinstance(node, ast.ImportFrom):
492 518 # Resolve the full imported module name.
493 519 if node.level > 0:
494 fullname = '.'.join(module.split('.')[:-node.level])
520 fullname = '.'.join(module.split('.')[: -node.level])
495 521 if node.module:
496 522 fullname += '.%s' % node.module
497 523 else:
@@ -508,7 +534,8 b' def verify_modern_convention(module, roo'
508 534 if not fullname or (
509 535 fullname in stdlib_modules
510 536 and fullname not in localmods
511 and fullname + '.__init__' not in localmods):
537 and fullname + '.__init__' not in localmods
538 ):
512 539 yield msg('relative import of stdlib module')
513 540 else:
514 541 seenlocal = fullname
@@ -518,19 +545,24 b' def verify_modern_convention(module, roo'
518 545 found = fromlocal(node.module, node.level)
519 546 if found and found[2]: # node.module is a package
520 547 prefix = found[0] + '.'
521 symbols = (n.name for n in node.names
522 if not fromlocal(prefix + n.name))
548 symbols = (
549 n.name for n in node.names if not fromlocal(prefix + n.name)
550 )
523 551 else:
524 552 symbols = (n.name for n in node.names)
525 553 symbols = [sym for sym in symbols if sym not in directsymbols]
526 554 if node.module and node.col_offset == root_col_offset:
527 555 if symbols and fullname not in allowsymbolimports:
528 yield msg('direct symbol import %s from %s',
529 ', '.join(symbols), fullname)
556 yield msg(
557 'direct symbol import %s from %s',
558 ', '.join(symbols),
559 fullname,
560 )
530 561
531 562 if symbols and seennonsymbollocal:
532 yield msg('symbol import follows non-symbol import: %s',
533 fullname)
563 yield msg(
564 'symbol import follows non-symbol import: %s', fullname
565 )
534 566 if not symbols and fullname not in stdlib_modules:
535 567 seennonsymbollocal = True
536 568
@@ -538,15 +570,19 b' def verify_modern_convention(module, roo'
538 570 assert node.level
539 571
540 572 # Only allow 1 group per level.
541 if (node.level in seenlevels
542 and node.col_offset == root_col_offset):
543 yield msg('multiple "from %s import" statements',
544 '.' * node.level)
573 if (
574 node.level in seenlevels
575 and node.col_offset == root_col_offset
576 ):
577 yield msg(
578 'multiple "from %s import" statements', '.' * node.level
579 )
545 580
546 581 # Higher-level groups come before lower-level groups.
547 582 if any(node.level > l for l in seenlevels):
548 yield msg('higher-level import should come first: %s',
549 fullname)
583 yield msg(
584 'higher-level import should come first: %s', fullname
585 )
550 586
551 587 seenlevels.add(node.level)
552 588
@@ -556,14 +592,23 b' def verify_modern_convention(module, roo'
556 592
557 593 for n in node.names:
558 594 if lastentryname and n.name < lastentryname:
559 yield msg('imports from %s not lexically sorted: %s < %s',
560 fullname, n.name, lastentryname)
595 yield msg(
596 'imports from %s not lexically sorted: %s < %s',
597 fullname,
598 n.name,
599 lastentryname,
600 )
561 601
562 602 lastentryname = n.name
563 603
564 604 if n.name in requirealias and n.asname != requirealias[n.name]:
565 yield msg('%s from %s must be "as" aliased to %s',
566 n.name, fullname, requirealias[n.name])
605 yield msg(
606 '%s from %s must be "as" aliased to %s',
607 n.name,
608 fullname,
609 requirealias[n.name],
610 )
611
567 612
568 613 def verify_stdlib_on_own_line(root):
569 614 """Given some python source, verify that stdlib imports are done
@@ -582,13 +627,20 b' def verify_stdlib_on_own_line(root):'
582 627 for n in node.names:
583 628 from_stdlib[n.name in stdlib_modules].append(n.name)
584 629 if from_stdlib[True] and from_stdlib[False]:
585 yield ('mixed imports\n stdlib: %s\n relative: %s' %
586 (', '.join(sorted(from_stdlib[True])),
587 ', '.join(sorted(from_stdlib[False]))), node.lineno)
630 yield (
631 'mixed imports\n stdlib: %s\n relative: %s'
632 % (
633 ', '.join(sorted(from_stdlib[True])),
634 ', '.join(sorted(from_stdlib[False])),
635 ),
636 node.lineno,
637 )
638
588 639
589 640 class CircularImport(Exception):
590 641 pass
591 642
643
592 644 def checkmod(mod, imports):
593 645 shortest = {}
594 646 visit = [[mod]]
@@ -603,6 +655,7 b' def checkmod(mod, imports):'
603 655 continue
604 656 visit.append(path + [i])
605 657
658
606 659 def rotatecycle(cycle):
607 660 """arrange a cycle so that the lexicographically first module listed first
608 661
@@ -613,6 +666,7 b' def rotatecycle(cycle):'
613 666 idx = cycle.index(lowest)
614 667 return cycle[idx:] + cycle[:idx] + [lowest]
615 668
669
616 670 def find_cycles(imports):
617 671 """Find cycles in an already-loaded import graph.
618 672
@@ -636,9 +690,11 b' def find_cycles(imports):'
636 690 cycles.add(" -> ".join(rotatecycle(cycle)))
637 691 return cycles
638 692
693
639 694 def _cycle_sortkey(c):
640 695 return len(c), c
641 696
697
642 698 def embedded(f, modname, src):
643 699 """Extract embedded python code
644 700
@@ -680,6 +736,7 b' def embedded(f, modname, src):'
680 736 modname = modname.decode('utf8')
681 737 yield code, "%s[%d]" % (modname, starts), name, starts - 1
682 738
739
683 740 def sources(f, modname):
684 741 """Yields possibly multiple sources from a filepath
685 742
@@ -700,6 +757,7 b' def sources(f, modname):'
700 757 for script, modname, t, line in embedded(f, modname, src):
701 758 yield script, modname.encode('utf8'), t, line
702 759
760
703 761 def main(argv):
704 762 if len(argv) < 2 or (argv[1] == '-' and len(argv) > 2):
705 763 print('Usage: %s {-|file [file] [file] ...}')
@@ -721,15 +779,19 b' def main(argv):'
721 779 for src, modname, name, line in sources(source_path, localmodname):
722 780 try:
723 781 used_imports[modname] = sorted(
724 imported_modules(src, modname, name, localmods,
725 ignore_nested=True))
726 for error, lineno in verify_import_convention(modname, src,
727 localmods):
782 imported_modules(
783 src, modname, name, localmods, ignore_nested=True
784 )
785 )
786 for error, lineno in verify_import_convention(
787 modname, src, localmods
788 ):
728 789 any_errors = True
729 790 print('%s:%d: %s' % (source_path, lineno + line, error))
730 791 except SyntaxError as e:
731 print('%s:%d: SyntaxError: %s' %
732 (source_path, e.lineno + line, e))
792 print(
793 '%s:%d: SyntaxError: %s' % (source_path, e.lineno + line, e)
794 )
733 795 cycles = find_cycles(used_imports)
734 796 if cycles:
735 797 firstmods = set()
@@ -745,5 +807,6 b' def main(argv):'
745 807 any_errors = True
746 808 return any_errors != 0
747 809
810
748 811 if __name__ == '__main__':
749 812 sys.exit(int(main(sys.argv)))
@@ -8,6 +8,7 b' from __future__ import absolute_import'
8 8
9 9 from . import repoview
10 10
11
11 12 def cachetocopy(srcrepo):
12 13 """return the list of cache file valuable to copy during a clone"""
13 14 # In local clones we're copying all nodes, not just served
@@ -14,6 +14,7 b' from . import ('
14 14 pycompat,
15 15 )
16 16
17
17 18 def addlines(fp, hunk, lena, lenb, a, b):
18 19 """Read lines from fp into the hunk
19 20
@@ -47,6 +48,7 b' def addlines(fp, hunk, lena, lenb, a, b)'
47 48 b.append(s[1:])
48 49 a.append(s)
49 50
51
50 52 def fixnewline(hunk, a, b):
51 53 """Fix up the last lines of a and b when the patch has no newline at EOF"""
52 54 l = hunk[-1]
@@ -62,6 +64,7 b' def fixnewline(hunk, a, b):'
62 64 a[-1] = hline
63 65 hunk[-1] = hline
64 66
67
65 68 def testhunk(a, b, bstart):
66 69 """Compare the lines in a with the lines in b
67 70
@@ -15,6 +15,7 b' from . import ('
15 15 util,
16 16 )
17 17
18
18 19 class dirstateguard(util.transactional):
19 20 '''Restore dirstate at unexpected failure.
20 21
@@ -34,14 +35,16 b' class dirstateguard(util.transactional):'
34 35 self._active = False
35 36 self._closed = False
36 37 self._backupname = 'dirstate.backup.%s.%d' % (name, id(self))
37 self._narrowspecbackupname = ('narrowspec.backup.%s.%d' %
38 (name, id(self)))
38 self._narrowspecbackupname = 'narrowspec.backup.%s.%d' % (
39 name,
40 id(self),
41 )
39 42 repo.dirstate.savebackup(repo.currenttransaction(), self._backupname)
40 43 narrowspec.savewcbackup(repo, self._narrowspecbackupname)
41 44 self._active = True
42 45
43 46 def __del__(self):
44 if self._active: # still active
47 if self._active: # still active
45 48 # this may occur, even if this class is used correctly:
46 49 # for example, releasing other resources like transaction
47 50 # may raise exception before ``dirstateguard.release`` in
@@ -49,27 +52,33 b' class dirstateguard(util.transactional):'
49 52 self._abort()
50 53
51 54 def close(self):
52 if not self._active: # already inactivated
53 msg = (_("can't close already inactivated backup: %s")
54 % self._backupname)
55 if not self._active: # already inactivated
56 msg = (
57 _("can't close already inactivated backup: %s")
58 % self._backupname
59 )
55 60 raise error.Abort(msg)
56 61
57 self._repo.dirstate.clearbackup(self._repo.currenttransaction(),
58 self._backupname)
62 self._repo.dirstate.clearbackup(
63 self._repo.currenttransaction(), self._backupname
64 )
59 65 narrowspec.clearwcbackup(self._repo, self._narrowspecbackupname)
60 66 self._active = False
61 67 self._closed = True
62 68
63 69 def _abort(self):
64 70 narrowspec.restorewcbackup(self._repo, self._narrowspecbackupname)
65 self._repo.dirstate.restorebackup(self._repo.currenttransaction(),
66 self._backupname)
71 self._repo.dirstate.restorebackup(
72 self._repo.currenttransaction(), self._backupname
73 )
67 74 self._active = False
68 75
69 76 def release(self):
70 77 if not self._closed:
71 if not self._active: # already inactivated
72 msg = (_("can't release already inactivated backup: %s")
73 % self._backupname)
78 if not self._active: # already inactivated
79 msg = (
80 _("can't release already inactivated backup: %s")
81 % self._backupname
82 )
74 83 raise error.Abort(msg)
75 84 self._abort()
@@ -43,8 +43,9 b' class httpsendfile(object):'
43 43 # requires authentication. Since we can't know until we try
44 44 # once whether authentication will be required, just lie to
45 45 # the user and maybe the push succeeds suddenly at 50%.
46 self._progress = ui.makeprogress(_('sending'), unit=_('kb'),
47 total=(self.length // 1024 * 2))
46 self._progress = ui.makeprogress(
47 _('sending'), unit=_('kb'), total=(self.length // 1024 * 2)
48 )
48 49
49 50 def read(self, *args, **kwargs):
50 51 ret = self._data.read(*args, **kwargs)
@@ -61,6 +62,7 b' class httpsendfile(object):'
61 62 def __exit__(self, exc_type, exc_val, exc_tb):
62 63 self.close()
63 64
65
64 66 # moved here from url.py to avoid a cycle
65 67 def readauthforuri(ui, uri, user):
66 68 uri = pycompat.bytesurl(uri)
@@ -109,10 +111,18 b' def readauthforuri(ui, uri, user):'
109 111 schemes, prefix = [p[0]], p[1]
110 112 else:
111 113 schemes = (auth.get('schemes') or 'https').split()
112 if ((prefix == '*' or hostpath.startswith(prefix)) and
113 (len(prefix) > bestlen or (len(prefix) == bestlen and
114 not bestuser and 'username' in auth))
115 and scheme in schemes):
114 if (
115 (prefix == '*' or hostpath.startswith(prefix))
116 and (
117 len(prefix) > bestlen
118 or (
119 len(prefix) == bestlen
120 and not bestuser
121 and 'username' in auth
122 )
123 )
124 and scheme in schemes
125 ):
116 126 bestlen = len(prefix)
117 127 bestauth = group, auth
118 128 bestuser = auth.get('username')
@@ -15,11 +15,13 b' from . import ('
15 15 pycompat,
16 16 )
17 17
18
18 19 def _sizep(x):
19 20 # i18n: "size" is a keyword
20 21 expr = filesetlang.getstring(x, _("size requires an expression"))
21 22 return fileset.sizematcher(expr)
22 23
24
23 25 def _compile(tree):
24 26 if not tree:
25 27 raise error.ParseError(_("missing argument"))
@@ -28,20 +30,23 b' def _compile(tree):'
28 30 return _compile(tree[1])
29 31 elif op in {'symbol', 'string', 'kindpat'}:
30 32 name = filesetlang.getpattern(tree, {'path'}, _('invalid file pattern'))
31 if name.startswith('**'): # file extension test, ex. "**.tar.gz"
33 if name.startswith('**'): # file extension test, ex. "**.tar.gz"
32 34 ext = name[2:]
33 35 for c in pycompat.bytestr(ext):
34 36 if c in '*{}[]?/\\':
35 37 raise error.ParseError(_('reserved character: %s') % c)
36 38 return lambda n, s: n.endswith(ext)
37 elif name.startswith('path:'): # directory or full path test
38 p = name[5:] # prefix
39 elif name.startswith('path:'): # directory or full path test
40 p = name[5:] # prefix
39 41 pl = len(p)
40 f = lambda n, s: n.startswith(p) and (len(n) == pl
41 or n[pl:pl + 1] == '/')
42 f = lambda n, s: n.startswith(p) and (
43 len(n) == pl or n[pl : pl + 1] == '/'
44 )
42 45 return f
43 raise error.ParseError(_("unsupported file pattern: %s") % name,
44 hint=_('paths must be prefixed with "path:"'))
46 raise error.ParseError(
47 _("unsupported file pattern: %s") % name,
48 hint=_('paths must be prefixed with "path:"'),
49 )
45 50 elif op in {'or', 'patterns'}:
46 51 funcs = [_compile(x) for x in tree[1:]]
47 52 return lambda n, s: any(f(n, s) for f in funcs)
@@ -63,15 +68,18 b' def _compile(tree):'
63 68 return symbols[name]
64 69
65 70 raise error.UnknownIdentifier(name, symbols.keys())
66 elif op == 'minus': # equivalent to 'x and not y'
71 elif op == 'minus': # equivalent to 'x and not y'
67 72 func1 = _compile(tree[1])
68 73 func2 = _compile(tree[2])
69 74 return lambda n, s: func1(n, s) and not func2(n, s)
70 75 elif op == 'list':
71 raise error.ParseError(_("can't use a list in this context"),
72 hint=_('see \'hg help "filesets.x or y"\''))
76 raise error.ParseError(
77 _("can't use a list in this context"),
78 hint=_('see \'hg help "filesets.x or y"\''),
79 )
73 80 raise error.ProgrammingError('illegal tree: %r' % (tree,))
74 81
82
75 83 def compile(text):
76 84 """generate a function (path, size) -> bool from filter specification.
77 85
@@ -20,6 +20,7 b' def bin(s):'
20 20 except binascii.Error as e:
21 21 raise TypeError(e)
22 22
23
23 24 nullrev = -1
24 25 # In hex, this is '0000000000000000000000000000000000000000'
25 26 nullid = b"\0" * 20
@@ -38,10 +39,11 b' wdirfilenodeids = {newnodeid, addednodei'
38 39
39 40 # pseudo identifiers for working directory
40 41 # (they are experimental, so don't add too many dependencies on them)
41 wdirrev = 0x7fffffff
42 wdirrev = 0x7FFFFFFF
42 43 # In hex, this is 'ffffffffffffffffffffffffffffffffffffffff'
43 44 wdirid = b"\xff" * 20
44 45 wdirhex = hex(wdirid)
45 46
47
46 48 def short(node):
47 49 return hex(node[:6])
@@ -39,6 +39,7 b" policy = b'allow'"
39 39
40 40 try:
41 41 from . import __modulepolicy__
42
42 43 policy = __modulepolicy__.modulepolicy
43 44 except ImportError:
44 45 pass
@@ -57,6 +58,7 b' if sys.version_info[0] >= 3:'
57 58 else:
58 59 policy = os.environ.get(r'HGMODULEPOLICY', policy)
59 60
61
60 62 def _importfrom(pkgname, modname):
61 63 # from .<pkgname> import <modname> (where . is looked through this module)
62 64 fakelocals = {}
@@ -69,6 +71,7 b' def _importfrom(pkgname, modname):'
69 71 getattr(mod, r'__doc__', None)
70 72 return fakelocals[modname]
71 73
74
72 75 # keep in sync with "version" in C modules
73 76 _cextversions = {
74 77 (r'cext', r'base85'): 1,
@@ -86,13 +89,17 b' def _importfrom(pkgname, modname):'
86 89 (r'cffi', r'parsers'): (r'pure', r'parsers'),
87 90 }
88 91
92
89 93 def _checkmod(pkgname, modname, mod):
90 94 expected = _cextversions.get((pkgname, modname))
91 95 actual = getattr(mod, r'version', None)
92 96 if actual != expected:
93 raise ImportError(r'cannot import module %s.%s '
94 r'(expected version: %d, actual: %r)'
95 % (pkgname, modname, expected, actual))
97 raise ImportError(
98 r'cannot import module %s.%s '
99 r'(expected version: %d, actual: %r)'
100 % (pkgname, modname, expected, actual)
101 )
102
96 103
97 104 def importmod(modname):
98 105 """Import module according to policy and check API version"""
@@ -114,10 +121,12 b' def importmod(modname):'
114 121 pn, mn = _modredirects.get((purepkg, modname), (purepkg, modname))
115 122 return _importfrom(pn, mn)
116 123
124
117 125 def _isrustpermissive():
118 126 """Assuming the policy is a Rust one, tell if it's permissive."""
119 127 return policy.endswith(b'-allow')
120 128
129
121 130 def importrust(modname, member=None, default=None):
122 131 """Import Rust module according to policy and availability.
123 132
@@ -14,6 +14,7 b' from . import ('
14 14 phases,
15 15 )
16 16
17
17 18 def _nslist(repo):
18 19 n = {}
19 20 for k in _namespaces:
@@ -22,36 +23,45 b' def _nslist(repo):'
22 23 n.pop('obsolete')
23 24 return n
24 25
25 _namespaces = {"namespaces": (lambda *x: False, _nslist),
26 "bookmarks": (bookmarks.pushbookmark, bookmarks.listbookmarks),
27 "phases": (phases.pushphase, phases.listphases),
28 "obsolete": (obsolete.pushmarker, obsolete.listmarkers),
29 }
26
27 _namespaces = {
28 "namespaces": (lambda *x: False, _nslist),
29 "bookmarks": (bookmarks.pushbookmark, bookmarks.listbookmarks),
30 "phases": (phases.pushphase, phases.listphases),
31 "obsolete": (obsolete.pushmarker, obsolete.listmarkers),
32 }
33
30 34
31 35 def register(namespace, pushkey, listkeys):
32 36 _namespaces[namespace] = (pushkey, listkeys)
33 37
38
34 39 def _get(namespace):
35 40 return _namespaces.get(namespace, (lambda *x: False, lambda *x: {}))
36 41
42
37 43 def push(repo, namespace, key, old, new):
38 44 '''should succeed iff value was old'''
39 45 pk = _get(namespace)[0]
40 46 return pk(repo, key, old, new)
41 47
48
42 49 def list(repo, namespace):
43 50 '''return a dict'''
44 51 lk = _get(namespace)[1]
45 52 return lk(repo)
46 53
54
47 55 encode = encoding.fromlocal
48 56
49 57 decode = encoding.tolocal
50 58
59
51 60 def encodekeys(keys):
52 61 """encode the content of a pushkey namespace for exchange over the wire"""
53 62 return '\n'.join(['%s\t%s' % (encode(k), encode(v)) for k, v in keys])
54 63
64
55 65 def decodekeys(data):
56 66 """decode the content of a pushkey namespace from exchange over the wire"""
57 67 result = {}
@@ -24,15 +24,18 b' fallbackpager = scmplatform.fallbackpage'
24 24 systemrcpath = scmplatform.systemrcpath
25 25 userrcpath = scmplatform.userrcpath
26 26
27
27 28 def _expandrcpath(path):
28 29 '''path could be a file or a directory. return a list of file paths'''
29 30 p = util.expandpath(path)
30 31 if os.path.isdir(p):
31 32 join = os.path.join
32 return sorted(join(p, f) for f, k in util.listdir(p)
33 if f.endswith('.rc'))
33 return sorted(
34 join(p, f) for f, k in util.listdir(p) if f.endswith('.rc')
35 )
34 36 return [p]
35 37
38
36 39 def envrcitems(env=None):
37 40 '''Return [(section, name, value, source)] config items.
38 41
@@ -55,6 +58,7 b' def envrcitems(env=None):'
55 58 result.append((section, configname, env[envname], '$%s' % envname))
56 59 return result
57 60
61
58 62 def defaultrcpath():
59 63 '''return rc paths in default.d'''
60 64 path = []
@@ -63,6 +67,7 b' def defaultrcpath():'
63 67 path = _expandrcpath(defaultpath)
64 68 return path
65 69
70
66 71 def rccomponents():
67 72 '''return an ordered [(type, obj)] about where to load configs.
68 73
@@ -92,6 +97,7 b' def rccomponents():'
92 97 _rccomponents.extend(normpaths(userrcpath()))
93 98 return _rccomponents
94 99
100
95 101 def defaultpagerenv():
96 102 '''return a dict of default environment variables and their values,
97 103 intended to be set before starting a pager.
@@ -16,6 +16,7 b' from . import ('
16 16 revset,
17 17 )
18 18
19
19 20 def precheck(repo, revs, action='rewrite'):
20 21 """check if revs can be rewritten
21 22 action is used to control the error message.
@@ -23,7 +24,7 b" def precheck(repo, revs, action='rewrite"
23 24 Make sure this function is called after taking the lock.
24 25 """
25 26 if node.nullrev in revs:
26 msg = _("cannot %s null changeset") % (action)
27 msg = _("cannot %s null changeset") % action
27 28 hint = _("no changeset checked out")
28 29 raise error.Abort(msg, hint=hint)
29 30
@@ -32,7 +33,7 b" def precheck(repo, revs, action='rewrite"
32 33
33 34 publicrevs = repo.revs('%ld and public()', revs)
34 35 if publicrevs:
35 msg = _("cannot %s public changesets") % (action)
36 msg = _("cannot %s public changesets") % action
36 37 hint = _("see 'hg help phases' for details")
37 38 raise error.Abort(msg, hint=hint)
38 39
@@ -40,6 +41,7 b" def precheck(repo, revs, action='rewrite"
40 41 if newunstable:
41 42 raise error.Abort(_("cannot %s changeset with children") % action)
42 43
44
43 45 def disallowednewunstable(repo, revs):
44 46 """Checks whether editing the revs will create new unstable changesets and
45 47 are we allowed to create them.
@@ -18,17 +18,23 b' from . import ('
18 18 # 'less' as the default seems reasonable.
19 19 fallbackpager = 'less'
20 20
21
21 22 def _rcfiles(path):
22 23 rcs = [os.path.join(path, 'hgrc')]
23 24 rcdir = os.path.join(path, 'hgrc.d')
24 25 try:
25 rcs.extend([os.path.join(rcdir, f)
26 for f, kind in util.listdir(rcdir)
27 if f.endswith(".rc")])
26 rcs.extend(
27 [
28 os.path.join(rcdir, f)
29 for f, kind in util.listdir(rcdir)
30 if f.endswith(".rc")
31 ]
32 )
28 33 except OSError:
29 34 pass
30 35 return rcs
31 36
37
32 38 def systemrcpath():
33 39 path = []
34 40 if pycompat.sysplatform == 'plan9':
@@ -43,6 +49,7 b' def systemrcpath():'
43 49 path.extend(_rcfiles('/' + root))
44 50 return path
45 51
52
46 53 def userrcpath():
47 54 if pycompat.sysplatform == 'plan9':
48 55 return [encoding.environ['home'] + '/lib/hgrc']
@@ -53,12 +60,16 b' def userrcpath():'
53 60 if confighome is None or not os.path.isabs(confighome):
54 61 confighome = os.path.expanduser('~/.config')
55 62
56 return [os.path.expanduser('~/.hgrc'),
57 os.path.join(confighome, 'hg', 'hgrc')]
63 return [
64 os.path.expanduser('~/.hgrc'),
65 os.path.join(confighome, 'hg', 'hgrc'),
66 ]
67
58 68
59 69 def termsize(ui):
60 70 try:
61 71 import termios
72
62 73 TIOCGWINSZ = termios.TIOCGWINSZ # unavailable on IRIX (issue3449)
63 74 except (AttributeError, ImportError):
64 75 return 80, 24
@@ -11,6 +11,7 b' from . import ('
11 11
12 12 try:
13 13 import _winreg as winreg
14
14 15 winreg.CloseKey
15 16 except ImportError:
16 17 import winreg
@@ -18,6 +19,7 b' except ImportError:'
18 19 # MS-DOS 'more' is the only pager available by default on Windows.
19 20 fallbackpager = 'more'
20 21
22
21 23 def systemrcpath():
22 24 '''return default os-specific hgrc search path'''
23 25 rcpath = []
@@ -32,8 +34,9 b' def systemrcpath():'
32 34 if f.endswith('.rc'):
33 35 rcpath.append(os.path.join(progrcd, f))
34 36 # else look for a system rcpath in the registry
35 value = util.lookupreg('SOFTWARE\\Mercurial', None,
36 winreg.HKEY_LOCAL_MACHINE)
37 value = util.lookupreg(
38 'SOFTWARE\\Mercurial', None, winreg.HKEY_LOCAL_MACHINE
39 )
37 40 if not isinstance(value, str) or not value:
38 41 return rcpath
39 42 value = util.localpath(value)
@@ -46,16 +49,17 b' def systemrcpath():'
46 49 rcpath.append(os.path.join(p, f))
47 50 return rcpath
48 51
52
49 53 def userrcpath():
50 54 '''return os-specific hgrc search path to the user dir'''
51 55 home = os.path.expanduser('~')
52 path = [os.path.join(home, 'mercurial.ini'),
53 os.path.join(home, '.hgrc')]
56 path = [os.path.join(home, 'mercurial.ini'), os.path.join(home, '.hgrc')]
54 57 userprofile = encoding.environ.get('USERPROFILE')
55 58 if userprofile and userprofile != home:
56 59 path.append(os.path.join(userprofile, 'mercurial.ini'))
57 60 path.append(os.path.join(userprofile, '.hgrc'))
58 61 return path
59 62
63
60 64 def termsize(ui):
61 65 return win32.termsize()
@@ -7,6 +7,7 b''
7 7
8 8 from __future__ import absolute_import
9 9
10
10 11 def getstack(repo, rev=None):
11 12 """return a sorted smartrev of the stack containing either rev if it is
12 13 not None or the current working directory parent.
General Comments 0
You need to be logged in to leave comments. Login now