diff --git a/contrib/import-checker.py b/contrib/import-checker.py --- a/contrib/import-checker.py +++ b/contrib/import-checker.py @@ -407,8 +407,6 @@ sorted. * Importing multiple modules via "import X, Y" is not allowed: use separate import statements. - * Importing multiple modules via "from X import ..." is allowed if using - parenthesis and one entry per line. * Only 1 relative import statement per import level ("from .", "from ..") is allowed. * Relative imports from higher levels must occur before lower levels. e.g. diff --git a/mercurial/cacheutil.py b/mercurial/cacheutil.py --- a/mercurial/cacheutil.py +++ b/mercurial/cacheutil.py @@ -8,14 +8,15 @@ from . import repoview + def cachetocopy(srcrepo): """return the list of cache file valuable to copy during a clone""" # In local clones we're copying all nodes, not just served # ones. Therefore copy all branch caches over. - cachefiles = ['branch2'] - cachefiles += ['branch2-%s' % f for f in repoview.filtertable] - cachefiles += ['rbc-names-v1', 'rbc-revs-v1'] - cachefiles += ['tags2'] - cachefiles += ['tags2-%s' % f for f in repoview.filtertable] - cachefiles += ['hgtagsfnodes1'] + cachefiles = ["branch2"] + cachefiles += ["branch2-%s" % f for f in repoview.filtertable] + cachefiles += ["rbc-names-v1", "rbc-revs-v1"] + cachefiles += ["tags2"] + cachefiles += ["tags2-%s" % f for f in repoview.filtertable] + cachefiles += ["hgtagsfnodes1"] return cachefiles diff --git a/mercurial/diffhelper.py b/mercurial/diffhelper.py --- a/mercurial/diffhelper.py +++ b/mercurial/diffhelper.py @@ -9,10 +9,8 @@ from .i18n import _ -from . import ( - error, - pycompat, -) +from . import error, pycompat + def addlines(fp, hunk, lena, lenb, a, b): """Read lines from fp into the hunk @@ -30,38 +28,40 @@ for i in pycompat.xrange(num): s = fp.readline() if not s: - raise error.ParseError(_('incomplete hunk')) + raise error.ParseError(_("incomplete hunk")) if s == "\\ No newline at end of file\n": fixnewline(hunk, a, b) continue - if s == '\n' or s == '\r\n': + if s == "\n" or s == "\r\n": # Some patches may be missing the control char # on empty lines. Supply a leading space. - s = ' ' + s + s = " " + s hunk.append(s) - if s.startswith('+'): + if s.startswith("+"): b.append(s[1:]) - elif s.startswith('-'): + elif s.startswith("-"): a.append(s) else: b.append(s[1:]) a.append(s) + def fixnewline(hunk, a, b): """Fix up the last lines of a and b when the patch has no newline at EOF""" l = hunk[-1] # tolerate CRLF in last line - if l.endswith('\r\n'): + if l.endswith("\r\n"): hline = l[:-2] else: hline = l[:-1] - if hline.startswith((' ', '+')): + if hline.startswith((" ", "+")): b[-1] = hline[1:] - if hline.startswith((' ', '-')): + if hline.startswith((" ", "-")): a[-1] = hline hunk[-1] = hline + def testhunk(a, b, bstart): """Compare the lines in a with the lines in b diff --git a/mercurial/dirstateguard.py b/mercurial/dirstateguard.py --- a/mercurial/dirstateguard.py +++ b/mercurial/dirstateguard.py @@ -9,14 +9,11 @@ from .i18n import _ -from . import ( - error, - narrowspec, - util, -) +from . import error, narrowspec, util + class dirstateguard(util.transactional): - '''Restore dirstate at unexpected failure. + """Restore dirstate at unexpected failure. At the construction, this class does: @@ -27,21 +24,23 @@ is invoked before ``close()``. This just removes the backup file at ``close()`` before ``release()``. - ''' + """ def __init__(self, repo, name): self._repo = repo self._active = False self._closed = False - self._backupname = 'dirstate.backup.%s.%d' % (name, id(self)) - self._narrowspecbackupname = ('narrowspec.backup.%s.%d' % - (name, id(self))) + self._backupname = "dirstate.backup.%s.%d" % (name, id(self)) + self._narrowspecbackupname = "narrowspec.backup.%s.%d" % ( + name, + id(self), + ) repo.dirstate.savebackup(repo.currenttransaction(), self._backupname) narrowspec.savebackup(repo, self._narrowspecbackupname) self._active = True def __del__(self): - if self._active: # still active + if self._active: # still active # this may occur, even if this class is used correctly: # for example, releasing other resources like transaction # may raise exception before ``dirstateguard.release`` in @@ -49,27 +48,33 @@ self._abort() def close(self): - if not self._active: # already inactivated - msg = (_("can't close already inactivated backup: %s") - % self._backupname) + if not self._active: # already inactivated + msg = ( + _("can't close already inactivated backup: %s") + % self._backupname + ) raise error.Abort(msg) - self._repo.dirstate.clearbackup(self._repo.currenttransaction(), - self._backupname) + self._repo.dirstate.clearbackup( + self._repo.currenttransaction(), self._backupname + ) narrowspec.clearbackup(self._repo, self._narrowspecbackupname) self._active = False self._closed = True def _abort(self): narrowspec.restorebackup(self._repo, self._narrowspecbackupname) - self._repo.dirstate.restorebackup(self._repo.currenttransaction(), - self._backupname) + self._repo.dirstate.restorebackup( + self._repo.currenttransaction(), self._backupname + ) self._active = False def release(self): if not self._closed: - if not self._active: # already inactivated - msg = (_("can't release already inactivated backup: %s") - % self._backupname) + if not self._active: # already inactivated + msg = ( + _("can't release already inactivated backup: %s") + % self._backupname + ) raise error.Abort(msg) self._abort() diff --git a/mercurial/httpconnection.py b/mercurial/httpconnection.py --- a/mercurial/httpconnection.py +++ b/mercurial/httpconnection.py @@ -13,10 +13,7 @@ import os from .i18n import _ -from . import ( - pycompat, - util, -) +from . import pycompat, util urlerr = util.urlerr urlreq = util.urlreq @@ -43,8 +40,9 @@ # requires authentication. Since we can't know until we try # once whether authentication will be required, just lie to # the user and maybe the push succeeds suddenly at 50%. - self._progress = ui.makeprogress(_('sending'), unit=_('kb'), - total=(self.length // 1024 * 2)) + self._progress = ui.makeprogress( + _("sending"), unit=_("kb"), total=(self.length // 1024 * 2) + ) def read(self, *args, **kwargs): ret = self._data.read(*args, **kwargs) @@ -61,49 +59,58 @@ def __exit__(self, exc_type, exc_val, exc_tb): self.close() + # moved here from url.py to avoid a cycle def readauthforuri(ui, uri, user): uri = pycompat.bytesurl(uri) # Read configuration groups = {} - for key, val in ui.configitems('auth'): - if key in ('cookiefile',): + for key, val in ui.configitems("auth"): + if key in ("cookiefile",): continue - if '.' not in key: + if "." not in key: ui.warn(_("ignoring invalid [auth] key '%s'\n") % key) continue - group, setting = key.rsplit('.', 1) + group, setting = key.rsplit(".", 1) gdict = groups.setdefault(group, {}) - if setting in ('username', 'cert', 'key'): + if setting in ("username", "cert", "key"): val = util.expandpath(val) gdict[setting] = val # Find the best match - scheme, hostpath = uri.split('://', 1) + scheme, hostpath = uri.split("://", 1) bestuser = None bestlen = 0 bestauth = None for group, auth in groups.iteritems(): - if user and user != auth.get('username', user): + if user and user != auth.get("username", user): # If a username was set in the URI, the entry username # must either match it or be unset continue - prefix = auth.get('prefix') + prefix = auth.get("prefix") if not prefix: continue - p = prefix.split('://', 1) + p = prefix.split("://", 1) if len(p) > 1: schemes, prefix = [p[0]], p[1] else: - schemes = (auth.get('schemes') or 'https').split() - if (prefix == '*' or hostpath.startswith(prefix)) and \ - (len(prefix) > bestlen or (len(prefix) == bestlen and \ - not bestuser and 'username' in auth)) \ - and scheme in schemes: + schemes = (auth.get("schemes") or "https").split() + if ( + (prefix == "*" or hostpath.startswith(prefix)) + and ( + len(prefix) > bestlen + or ( + len(prefix) == bestlen + and not bestuser + and "username" in auth + ) + ) + and scheme in schemes + ): bestlen = len(prefix) bestauth = group, auth - bestuser = auth.get('username') + bestuser = auth.get("username") if user and not bestuser: - auth['username'] = user + auth["username"] = user return bestauth diff --git a/mercurial/lsprofcalltree.py b/mercurial/lsprofcalltree.py --- a/mercurial/lsprofcalltree.py +++ b/mercurial/lsprofcalltree.py @@ -12,18 +12,20 @@ from __future__ import absolute_import -from . import ( - pycompat, -) +from . import pycompat + def label(code): if isinstance(code, str): # built-in functions ('~' sorts at the end) - return '~' + pycompat.sysbytes(code) + return "~" + pycompat.sysbytes(code) else: - return '%s %s:%d' % (pycompat.sysbytes(code.co_name), - pycompat.sysbytes(code.co_filename), - code.co_firstlineno) + return "%s %s:%d" % ( + pycompat.sysbytes(code.co_name), + pycompat.sysbytes(code.co_filename), + code.co_firstlineno, + ) + class KCacheGrind(object): def __init__(self, profiler): @@ -32,7 +34,7 @@ def output(self, out_file): self.out_file = out_file - out_file.write(b'events: Ticks\n') + out_file.write(b"events: Ticks\n") self._print_summary() for entry in self.data: self._entry(entry) @@ -42,24 +44,24 @@ for entry in self.data: totaltime = int(entry.totaltime * 1000) max_cost = max(max_cost, totaltime) - self.out_file.write(b'summary: %d\n' % max_cost) + self.out_file.write(b"summary: %d\n" % max_cost) def _entry(self, entry): out_file = self.out_file code = entry.code if isinstance(code, str): - out_file.write(b'fi=~\n') + out_file.write(b"fi=~\n") else: - out_file.write(b'fi=%s\n' % pycompat.sysbytes(code.co_filename)) + out_file.write(b"fi=%s\n" % pycompat.sysbytes(code.co_filename)) - out_file.write(b'fn=%s\n' % label(code)) + out_file.write(b"fn=%s\n" % label(code)) inlinetime = int(entry.inlinetime * 1000) if isinstance(code, str): - out_file.write(b'0 %d\n' % inlinetime) + out_file.write(b"0 %d\n" % inlinetime) else: - out_file.write(b'%d %d\n' % (code.co_firstlineno, inlinetime)) + out_file.write(b"%d %d\n" % (code.co_firstlineno, inlinetime)) # recursive calls are counted in entry.calls if entry.calls: @@ -75,19 +77,20 @@ for subentry in calls: self._subentry(lineno, subentry) - out_file.write(b'\n') + out_file.write(b"\n") def _subentry(self, lineno, subentry): out_file = self.out_file code = subentry.code - out_file.write(b'cfn=%s\n' % label(code)) + out_file.write(b"cfn=%s\n" % label(code)) if isinstance(code, str): - out_file.write(b'cfi=~\n') - out_file.write(b'calls=%d 0\n' % subentry.callcount) + out_file.write(b"cfi=~\n") + out_file.write(b"calls=%d 0\n" % subentry.callcount) else: - out_file.write(b'cfi=%s\n' % pycompat.sysbytes(code.co_filename)) - out_file.write(b'calls=%d %d\n' % ( - subentry.callcount, code.co_firstlineno)) + out_file.write(b"cfi=%s\n" % pycompat.sysbytes(code.co_filename)) + out_file.write( + b"calls=%d %d\n" % (subentry.callcount, code.co_firstlineno) + ) totaltime = int(subentry.totaltime * 1000) - out_file.write(b'%d %d\n' % (lineno, totaltime)) + out_file.write(b"%d %d\n" % (lineno, totaltime)) diff --git a/mercurial/mergeutil.py b/mercurial/mergeutil.py --- a/mercurial/mergeutil.py +++ b/mercurial/mergeutil.py @@ -9,14 +9,16 @@ from .i18n import _ -from . import ( - error, -) +from . import error + def checkunresolved(ms): if list(ms.unresolved()): - raise error.Abort(_("unresolved merge conflicts " - "(see 'hg help resolve')")) - if ms.mdstate() != 's' or list(ms.driverresolved()): - raise error.Abort(_('driver-resolved merge conflicts'), - hint=_('run "hg resolve --all" to resolve')) + raise error.Abort( + _("unresolved merge conflicts " "(see 'hg help resolve')") + ) + if ms.mdstate() != "s" or list(ms.driverresolved()): + raise error.Abort( + _("driver-resolved merge conflicts"), + hint=_('run "hg resolve --all" to resolve'), + ) diff --git a/mercurial/minifileset.py b/mercurial/minifileset.py --- a/mercurial/minifileset.py +++ b/mercurial/minifileset.py @@ -8,54 +8,54 @@ from __future__ import absolute_import from .i18n import _ -from . import ( - error, - fileset, - filesetlang, - pycompat, -) +from . import error, fileset, filesetlang, pycompat + def _sizep(x): # i18n: "size" is a keyword expr = filesetlang.getstring(x, _("size requires an expression")) return fileset.sizematcher(expr) + def _compile(tree): if not tree: raise error.ParseError(_("missing argument")) op = tree[0] - if op == 'withstatus': + if op == "withstatus": return _compile(tree[1]) - elif op in {'symbol', 'string', 'kindpat'}: - name = filesetlang.getpattern(tree, {'path'}, _('invalid file pattern')) - if name.startswith('**'): # file extension test, ex. "**.tar.gz" + elif op in {"symbol", "string", "kindpat"}: + name = filesetlang.getpattern(tree, {"path"}, _("invalid file pattern")) + if name.startswith("**"): # file extension test, ex. "**.tar.gz" ext = name[2:] for c in pycompat.bytestr(ext): - if c in '*{}[]?/\\': - raise error.ParseError(_('reserved character: %s') % c) + if c in "*{}[]?/\\": + raise error.ParseError(_("reserved character: %s") % c) return lambda n, s: n.endswith(ext) - elif name.startswith('path:'): # directory or full path test - p = name[5:] # prefix + elif name.startswith("path:"): # directory or full path test + p = name[5:] # prefix pl = len(p) - f = lambda n, s: n.startswith(p) and (len(n) == pl - or n[pl:pl + 1] == '/') + f = lambda n, s: n.startswith(p) and ( + len(n) == pl or n[pl : pl + 1] == "/" + ) return f - raise error.ParseError(_("unsupported file pattern: %s") % name, - hint=_('paths must be prefixed with "path:"')) - elif op in {'or', 'patterns'}: + raise error.ParseError( + _("unsupported file pattern: %s") % name, + hint=_('paths must be prefixed with "path:"'), + ) + elif op in {"or", "patterns"}: funcs = [_compile(x) for x in tree[1:]] return lambda n, s: any(f(n, s) for f in funcs) - elif op == 'and': + elif op == "and": func1 = _compile(tree[1]) func2 = _compile(tree[2]) return lambda n, s: func1(n, s) and func2(n, s) - elif op == 'not': + elif op == "not": return lambda n, s: not _compile(tree[1])(n, s) - elif op == 'func': + elif op == "func": symbols = { - 'all': lambda n, s: True, - 'none': lambda n, s: False, - 'size': lambda n, s: _sizep(tree[2])(s), + "all": lambda n, s: True, + "none": lambda n, s: False, + "size": lambda n, s: _sizep(tree[2])(s), } name = filesetlang.getsymbol(tree[1]) @@ -63,14 +63,17 @@ return symbols[name] raise error.UnknownIdentifier(name, symbols.keys()) - elif op == 'minus': # equivalent to 'x and not y' + elif op == "minus": # equivalent to 'x and not y' func1 = _compile(tree[1]) func2 = _compile(tree[2]) return lambda n, s: func1(n, s) and not func2(n, s) - elif op == 'list': - raise error.ParseError(_("can't use a list in this context"), - hint=_('see \'hg help "filesets.x or y"\'')) - raise error.ProgrammingError('illegal tree: %r' % (tree,)) + elif op == "list": + raise error.ParseError( + _("can't use a list in this context"), + hint=_("see 'hg help \"filesets.x or y\"'"), + ) + raise error.ProgrammingError("illegal tree: %r" % (tree,)) + def compile(text): """generate a function (path, size) -> bool from filter specification. diff --git a/mercurial/node.py b/mercurial/node.py --- a/mercurial/node.py +++ b/mercurial/node.py @@ -20,6 +20,7 @@ except binascii.Error as e: raise TypeError(e) + nullrev = -1 # In hex, this is '0000000000000000000000000000000000000000' nullid = b"\0" * 20 @@ -28,20 +29,21 @@ # Phony node value to stand-in for new files in some uses of # manifests. # In hex, this is '2121212121212121212121212121212121212121' -newnodeid = '!!!!!!!!!!!!!!!!!!!!' +newnodeid = "!!!!!!!!!!!!!!!!!!!!" # In hex, this is '3030303030303030303030303030306164646564' -addednodeid = '000000000000000added' +addednodeid = "000000000000000added" # In hex, this is '3030303030303030303030306d6f646966696564' -modifiednodeid = '000000000000modified' +modifiednodeid = "000000000000modified" wdirfilenodeids = {newnodeid, addednodeid, modifiednodeid} # pseudo identifiers for working directory # (they are experimental, so don't add too many dependencies on them) -wdirrev = 0x7fffffff +wdirrev = 0x7FFFFFFF # In hex, this is 'ffffffffffffffffffffffffffffffffffffffff' wdirid = b"\xff" * 20 wdirhex = hex(wdirid) + def short(node): return hex(node[:6]) diff --git a/mercurial/policy.py b/mercurial/policy.py --- a/mercurial/policy.py +++ b/mercurial/policy.py @@ -21,18 +21,19 @@ # By default, fall back to the pure modules so the in-place build can # run without recompiling the C extensions. This will be overridden by # __modulepolicy__ generated by setup.py. -policy = b'allow' +policy = b"allow" _packageprefs = { # policy: (versioned package, pure package) - b'c': (r'cext', None), - b'allow': (r'cext', r'pure'), - b'cffi': (r'cffi', None), - b'cffi-allow': (r'cffi', r'pure'), - b'py': (None, r'pure'), + b"c": (r"cext", None), + b"allow": (r"cext", r"pure"), + b"cffi": (r"cffi", None), + b"cffi-allow": (r"cffi", r"pure"), + b"py": (None, r"pure"), } try: from . import __modulepolicy__ + policy = __modulepolicy__.modulepolicy except ImportError: pass @@ -41,15 +42,16 @@ # # The canonical way to do this is to test platform.python_implementation(). # But we don't import platform and don't bloat for it here. -if r'__pypy__' in sys.builtin_module_names: - policy = b'cffi' +if r"__pypy__" in sys.builtin_module_names: + policy = b"cffi" # Environment variable can always force settings. if sys.version_info[0] >= 3: - if r'HGMODULEPOLICY' in os.environ: - policy = os.environ[r'HGMODULEPOLICY'].encode(r'utf-8') + if r"HGMODULEPOLICY" in os.environ: + policy = os.environ[r"HGMODULEPOLICY"].encode(r"utf-8") else: - policy = os.environ.get(r'HGMODULEPOLICY', policy) + policy = os.environ.get(r"HGMODULEPOLICY", policy) + def _importfrom(pkgname, modname): # from . import (where . is looked through this module) @@ -58,42 +60,47 @@ try: fakelocals[modname] = mod = getattr(pkg, modname) except AttributeError: - raise ImportError(r'cannot import name %s' % modname) + raise ImportError(r"cannot import name %s" % modname) # force import; fakelocals[modname] may be replaced with the real module - getattr(mod, r'__doc__', None) + getattr(mod, r"__doc__", None) return fakelocals[modname] + # keep in sync with "version" in C modules _cextversions = { - (r'cext', r'base85'): 1, - (r'cext', r'bdiff'): 3, - (r'cext', r'mpatch'): 1, - (r'cext', r'osutil'): 4, - (r'cext', r'parsers'): 11, + (r"cext", r"base85"): 1, + (r"cext", r"bdiff"): 3, + (r"cext", r"mpatch"): 1, + (r"cext", r"osutil"): 4, + (r"cext", r"parsers"): 11, } # map import request to other package or module _modredirects = { - (r'cext', r'charencode'): (r'cext', r'parsers'), - (r'cffi', r'base85'): (r'pure', r'base85'), - (r'cffi', r'charencode'): (r'pure', r'charencode'), - (r'cffi', r'parsers'): (r'pure', r'parsers'), + (r"cext", r"charencode"): (r"cext", r"parsers"), + (r"cffi", r"base85"): (r"pure", r"base85"), + (r"cffi", r"charencode"): (r"pure", r"charencode"), + (r"cffi", r"parsers"): (r"pure", r"parsers"), } + def _checkmod(pkgname, modname, mod): expected = _cextversions.get((pkgname, modname)) - actual = getattr(mod, r'version', None) + actual = getattr(mod, r"version", None) if actual != expected: - raise ImportError(r'cannot import module %s.%s ' - r'(expected version: %d, actual: %r)' - % (pkgname, modname, expected, actual)) + raise ImportError( + r"cannot import module %s.%s " + r"(expected version: %d, actual: %r)" + % (pkgname, modname, expected, actual) + ) + def importmod(modname): """Import module according to policy and check API version""" try: verpkg, purepkg = _packageprefs[policy] except KeyError: - raise ImportError(r'invalid HGMODULEPOLICY %r' % policy) + raise ImportError(r"invalid HGMODULEPOLICY %r" % policy) assert verpkg or purepkg if verpkg: pn, mn = _modredirects.get((verpkg, modname), (verpkg, modname)) diff --git a/mercurial/pushkey.py b/mercurial/pushkey.py --- a/mercurial/pushkey.py +++ b/mercurial/pushkey.py @@ -7,55 +7,60 @@ from __future__ import absolute_import -from . import ( - bookmarks, - encoding, - obsolete, - phases, -) +from . import bookmarks, encoding, obsolete, phases + def _nslist(repo): n = {} for k in _namespaces: n[k] = "" if not obsolete.isenabled(repo, obsolete.exchangeopt): - n.pop('obsolete') + n.pop("obsolete") return n -_namespaces = {"namespaces": (lambda *x: False, _nslist), - "bookmarks": (bookmarks.pushbookmark, bookmarks.listbookmarks), - "phases": (phases.pushphase, phases.listphases), - "obsolete": (obsolete.pushmarker, obsolete.listmarkers), - } + +_namespaces = { + "namespaces": (lambda *x: False, _nslist), + "bookmarks": (bookmarks.pushbookmark, bookmarks.listbookmarks), + "phases": (phases.pushphase, phases.listphases), + "obsolete": (obsolete.pushmarker, obsolete.listmarkers), +} + def register(namespace, pushkey, listkeys): _namespaces[namespace] = (pushkey, listkeys) + def _get(namespace): return _namespaces.get(namespace, (lambda *x: False, lambda *x: {})) + def push(repo, namespace, key, old, new): - '''should succeed iff value was old''' + """should succeed iff value was old""" pk = _get(namespace)[0] return pk(repo, key, old, new) + def list(repo, namespace): - '''return a dict''' + """return a dict""" lk = _get(namespace)[1] return lk(repo) + encode = encoding.fromlocal decode = encoding.tolocal + def encodekeys(keys): """encode the content of a pushkey namespace for exchange over the wire""" - return '\n'.join(['%s\t%s' % (encode(k), encode(v)) for k, v in keys]) + return "\n".join(["%s\t%s" % (encode(k), encode(v)) for k, v in keys]) + def decodekeys(data): """decode the content of a pushkey namespace from exchange over the wire""" result = {} for l in data.splitlines(): - k, v = l.split('\t') + k, v = l.split("\t") result[decode(k)] = decode(v) return result diff --git a/mercurial/rcutil.py b/mercurial/rcutil.py --- a/mercurial/rcutil.py +++ b/mercurial/rcutil.py @@ -9,11 +9,7 @@ import os -from . import ( - encoding, - pycompat, - util, -) +from . import encoding, pycompat, util if pycompat.iswindows: from . import scmwindows as scmplatform @@ -24,46 +20,50 @@ systemrcpath = scmplatform.systemrcpath userrcpath = scmplatform.userrcpath + def _expandrcpath(path): - '''path could be a file or a directory. return a list of file paths''' + """path could be a file or a directory. return a list of file paths""" p = util.expandpath(path) if os.path.isdir(p): join = os.path.join - return [join(p, f) for f, k in util.listdir(p) if f.endswith('.rc')] + return [join(p, f) for f, k in util.listdir(p) if f.endswith(".rc")] return [p] + def envrcitems(env=None): - '''Return [(section, name, value, source)] config items. + """Return [(section, name, value, source)] config items. The config items are extracted from environment variables specified by env, used to override systemrc, but not userrc. If env is not provided, encoding.environ will be used. - ''' + """ if env is None: env = encoding.environ checklist = [ - ('EDITOR', 'ui', 'editor'), - ('VISUAL', 'ui', 'editor'), - ('PAGER', 'pager', 'pager'), + ("EDITOR", "ui", "editor"), + ("VISUAL", "ui", "editor"), + ("PAGER", "pager", "pager"), ] result = [] for envname, section, configname in checklist: if envname not in env: continue - result.append((section, configname, env[envname], '$%s' % envname)) + result.append((section, configname, env[envname], "$%s" % envname)) return result + def defaultrcpath(): - '''return rc paths in default.d''' + """return rc paths in default.d""" path = [] - defaultpath = os.path.join(util.datapath, 'default.d') + defaultpath = os.path.join(util.datapath, "default.d") if os.path.isdir(defaultpath): path = _expandrcpath(defaultpath) return path + def rccomponents(): - '''return an ordered [(type, obj)] about where to load configs. + """return an ordered [(type, obj)] about where to load configs. respect $HGRCPATH. if $HGRCPATH is empty, only .hg/hgrc of current repo is used. if $HGRCPATH is not set, the platform default will be used. @@ -73,26 +73,27 @@ type could be either 'path' or 'items', if type is 'path', obj is a string, and is the config file path. if type is 'items', obj is a list of (section, name, value, source) that should fill the config directly. - ''' - envrc = ('items', envrcitems()) + """ + envrc = ("items", envrcitems()) - if 'HGRCPATH' in encoding.environ: + if "HGRCPATH" in encoding.environ: # assume HGRCPATH is all about user configs so environments can be # overridden. _rccomponents = [envrc] - for p in encoding.environ['HGRCPATH'].split(pycompat.ospathsep): + for p in encoding.environ["HGRCPATH"].split(pycompat.ospathsep): if not p: continue - _rccomponents.extend(('path', p) for p in _expandrcpath(p)) + _rccomponents.extend(("path", p) for p in _expandrcpath(p)) else: - normpaths = lambda paths: [('path', os.path.normpath(p)) for p in paths] + normpaths = lambda paths: [("path", os.path.normpath(p)) for p in paths] _rccomponents = normpaths(defaultrcpath() + systemrcpath()) _rccomponents.append(envrc) _rccomponents.extend(normpaths(userrcpath())) return _rccomponents + def defaultpagerenv(): - '''return a dict of default environment variables and their values, + """return a dict of default environment variables and their values, intended to be set before starting a pager. - ''' - return {'LESS': 'FRX', 'LV': '-c'} + """ + return {"LESS": "FRX", "LV": "-c"} diff --git a/mercurial/rewriteutil.py b/mercurial/rewriteutil.py --- a/mercurial/rewriteutil.py +++ b/mercurial/rewriteutil.py @@ -9,14 +9,10 @@ from .i18n import _ -from . import ( - error, - node, - obsolete, - revset, -) +from . import error, node, obsolete, revset -def precheck(repo, revs, action='rewrite'): + +def precheck(repo, revs, action="rewrite"): """check if revs can be rewritten action is used to control the error message. @@ -27,7 +23,7 @@ hint = _("no changeset checked out") raise error.Abort(msg, hint=hint) - publicrevs = repo.revs('%ld and public()', revs) + publicrevs = repo.revs("%ld and public()", revs) if len(repo[None].parents()) > 1: raise error.Abort(_("cannot %s while merging") % action) @@ -40,6 +36,7 @@ if newunstable: raise error.Abort(_("cannot %s changeset with children") % action) + def disallowednewunstable(repo, revs): """Checks whether editing the revs will create new unstable changesets and are we allowed to create them. diff --git a/mercurial/scmposix.py b/mercurial/scmposix.py --- a/mercurial/scmposix.py +++ b/mercurial/scmposix.py @@ -6,59 +6,66 @@ import os import sys -from . import ( - encoding, - pycompat, - util, -) +from . import encoding, pycompat, util # BSD 'more' escapes ANSI color sequences by default. This can be disabled by # $MORE variable, but there's no compatible option with Linux 'more'. Given # OS X is widely used and most modern Unix systems would have 'less', setting # 'less' as the default seems reasonable. -fallbackpager = 'less' +fallbackpager = "less" + def _rcfiles(path): - rcs = [os.path.join(path, 'hgrc')] - rcdir = os.path.join(path, 'hgrc.d') + rcs = [os.path.join(path, "hgrc")] + rcdir = os.path.join(path, "hgrc.d") try: - rcs.extend([os.path.join(rcdir, f) - for f, kind in util.listdir(rcdir) - if f.endswith(".rc")]) + rcs.extend( + [ + os.path.join(rcdir, f) + for f, kind in util.listdir(rcdir) + if f.endswith(".rc") + ] + ) except OSError: pass return rcs + def systemrcpath(): path = [] - if pycompat.sysplatform == 'plan9': - root = 'lib/mercurial' + if pycompat.sysplatform == "plan9": + root = "lib/mercurial" else: - root = 'etc/mercurial' + root = "etc/mercurial" # old mod_python does not set sys.argv - if len(getattr(sys, 'argv', [])) > 0: + if len(getattr(sys, "argv", [])) > 0: p = os.path.dirname(os.path.dirname(pycompat.sysargv[0])) - if p != '/': + if p != "/": path.extend(_rcfiles(os.path.join(p, root))) - path.extend(_rcfiles('/' + root)) + path.extend(_rcfiles("/" + root)) return path + def userrcpath(): - if pycompat.sysplatform == 'plan9': - return [encoding.environ['home'] + '/lib/hgrc'] + if pycompat.sysplatform == "plan9": + return [encoding.environ["home"] + "/lib/hgrc"] elif pycompat.isdarwin: - return [os.path.expanduser('~/.hgrc')] + return [os.path.expanduser("~/.hgrc")] else: - confighome = encoding.environ.get('XDG_CONFIG_HOME') + confighome = encoding.environ.get("XDG_CONFIG_HOME") if confighome is None or not os.path.isabs(confighome): - confighome = os.path.expanduser('~/.config') + confighome = os.path.expanduser("~/.config") - return [os.path.expanduser('~/.hgrc'), - os.path.join(confighome, 'hg', 'hgrc')] + return [ + os.path.expanduser("~/.hgrc"), + os.path.join(confighome, "hg", "hgrc"), + ] + def termsize(ui): try: import termios + TIOCGWINSZ = termios.TIOCGWINSZ # unavailable on IRIX (issue3449) except (AttributeError, ImportError): return 80, 24 @@ -71,8 +78,8 @@ continue if not os.isatty(fd): continue - arri = fcntl.ioctl(fd, TIOCGWINSZ, '\0' * 8) - height, width = array.array(r'h', arri)[:2] + arri = fcntl.ioctl(fd, TIOCGWINSZ, "\0" * 8) + height, width = array.array(r"h", arri)[:2] if width > 0 and height > 0: return width, height except ValueError: diff --git a/mercurial/scmwindows.py b/mercurial/scmwindows.py --- a/mercurial/scmwindows.py +++ b/mercurial/scmwindows.py @@ -2,60 +2,59 @@ import os -from . import ( - encoding, - pycompat, - util, - win32, -) +from . import encoding, pycompat, util, win32 try: import _winreg as winreg + winreg.CloseKey except ImportError: import winreg # MS-DOS 'more' is the only pager available by default on Windows. -fallbackpager = 'more' +fallbackpager = "more" + def systemrcpath(): - '''return default os-specific hgrc search path''' + """return default os-specific hgrc search path""" rcpath = [] filename = win32.executablepath() # Use mercurial.ini found in directory with hg.exe - progrc = os.path.join(os.path.dirname(filename), 'mercurial.ini') + progrc = os.path.join(os.path.dirname(filename), "mercurial.ini") rcpath.append(progrc) # Use hgrc.d found in directory with hg.exe - progrcd = os.path.join(os.path.dirname(filename), 'hgrc.d') + progrcd = os.path.join(os.path.dirname(filename), "hgrc.d") if os.path.isdir(progrcd): for f, kind in util.listdir(progrcd): - if f.endswith('.rc'): + if f.endswith(".rc"): rcpath.append(os.path.join(progrcd, f)) # else look for a system rcpath in the registry - value = util.lookupreg('SOFTWARE\\Mercurial', None, - winreg.HKEY_LOCAL_MACHINE) + value = util.lookupreg( + "SOFTWARE\\Mercurial", None, winreg.HKEY_LOCAL_MACHINE + ) if not isinstance(value, str) or not value: return rcpath value = util.localpath(value) for p in value.split(pycompat.ospathsep): - if p.lower().endswith('mercurial.ini'): + if p.lower().endswith("mercurial.ini"): rcpath.append(p) elif os.path.isdir(p): for f, kind in util.listdir(p): - if f.endswith('.rc'): + if f.endswith(".rc"): rcpath.append(os.path.join(p, f)) return rcpath + def userrcpath(): - '''return os-specific hgrc search path to the user dir''' - home = os.path.expanduser('~') - path = [os.path.join(home, 'mercurial.ini'), - os.path.join(home, '.hgrc')] - userprofile = encoding.environ.get('USERPROFILE') + """return os-specific hgrc search path to the user dir""" + home = os.path.expanduser("~") + path = [os.path.join(home, "mercurial.ini"), os.path.join(home, ".hgrc")] + userprofile = encoding.environ.get("USERPROFILE") if userprofile and userprofile != home: - path.append(os.path.join(userprofile, 'mercurial.ini')) - path.append(os.path.join(userprofile, '.hgrc')) + path.append(os.path.join(userprofile, "mercurial.ini")) + path.append(os.path.join(userprofile, ".hgrc")) return path + def termsize(ui): return win32.termsize() diff --git a/mercurial/stack.py b/mercurial/stack.py --- a/mercurial/stack.py +++ b/mercurial/stack.py @@ -7,10 +7,8 @@ from __future__ import absolute_import -from . import ( - revsetlang, - scmutil, -) +from . import revsetlang, scmutil + def getstack(repo, rev=None): """return a sorted smartrev of the stack containing either rev if it is @@ -20,9 +18,9 @@ the revision and are not merges. """ if rev is None: - rev = '.' + rev = "." - revspec = 'reverse(only(%s) and not public() and not ::merge())' + revspec = "reverse(only(%s) and not public() and not ::merge())" revset = revsetlang.formatspec(revspec, rev) revisions = scmutil.revrange(repo, [revset]) revisions.sort() diff --git a/mercurial/state.py b/mercurial/state.py --- a/mercurial/state.py +++ b/mercurial/state.py @@ -19,13 +19,9 @@ from __future__ import absolute_import -from . import ( - error, - util, -) -from .utils import ( - cborutil, -) +from . import error, util +from .utils import cborutil + class cmdstate(object): """a wrapper class to store the state of commands like `rebase`, `graft`, @@ -58,23 +54,25 @@ we use third-party library cbor to serialize data to write in the file. """ if not isinstance(version, int): - raise error.ProgrammingError("version of state file should be" - " an integer") + raise error.ProgrammingError( + "version of state file should be" " an integer" + ) - with self._repo.vfs(self.fname, 'wb', atomictemp=True) as fp: - fp.write('%d\n' % version) + with self._repo.vfs(self.fname, "wb", atomictemp=True) as fp: + fp.write("%d\n" % version) for chunk in cborutil.streamencode(data): fp.write(chunk) def _read(self): """reads the state file and returns a dictionary which contain data in the same format as it was before storing""" - with self._repo.vfs(self.fname, 'rb') as fp: + with self._repo.vfs(self.fname, "rb") as fp: try: int(fp.readline()) except ValueError: - raise error.CorruptedState("unknown version of state file" - " found") + raise error.CorruptedState( + "unknown version of state file" " found" + ) return cborutil.decodeall(fp.read())[0] diff --git a/mercurial/txnutil.py b/mercurial/txnutil.py --- a/mercurial/txnutil.py +++ b/mercurial/txnutil.py @@ -9,27 +9,27 @@ import errno -from . import ( - encoding, -) +from . import encoding + def mayhavepending(root): - '''return whether 'root' may have pending changes, which are + """return whether 'root' may have pending changes, which are visible to this process. - ''' - return root == encoding.environ.get('HG_PENDING') + """ + return root == encoding.environ.get("HG_PENDING") + def trypending(root, vfs, filename, **kwargs): - '''Open file to be read according to HG_PENDING environment variable + """Open file to be read according to HG_PENDING environment variable This opens '.pending' of specified 'filename' only when HG_PENDING is equal to 'root'. This returns '(fp, is_pending_opened)' tuple. - ''' + """ if mayhavepending(root): try: - return (vfs('%s.pending' % filename, **kwargs), True) + return (vfs("%s.pending" % filename, **kwargs), True) except IOError as inst: if inst.errno != errno.ENOENT: raise diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,3 @@ +[tool.black] +line-length = 80 +exclude = 'build/|wheelhouse/|dist/|packages/|\.hg/|\.mypy_cache/|\.venv/|mercurial/thirdparty/|hgext/fsmonitor/pywatchman/|contrib/python-zstandard/' diff --git a/tests/test-check-code.t b/tests/test-check-code.t --- a/tests/test-check-code.t +++ b/tests/test-check-code.t @@ -50,6 +50,7 @@ hg hgeditor hgweb.cgi + pyproject.toml setup.py Prevent adding modules which could be shadowed by ancient .so/.dylib.