Mercurial > public > mercurial-scm > hg-stable
diff mercurial/extensions.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 | 6a3872e34503 |
children | 687b865b95ad |
line wrap: on
line diff
--- a/mercurial/extensions.py Sat Oct 05 10:29:34 2019 -0400 +++ b/mercurial/extensions.py Sun Oct 06 09:45:02 2019 -0400 @@ -27,9 +27,7 @@ util, ) -from .utils import ( - stringutil, -) +from .utils import stringutil _extensions = {} _disabledextensions = {} @@ -47,13 +45,16 @@ 'shelve', } + def extensions(ui=None): if ui: + def enabled(name): for format in ['%s', 'hgext.%s']: conf = ui.config('extensions', format % name) if conf is not None and not conf.startswith('!'): return True + else: enabled = lambda name: True for name in _order: @@ -61,6 +62,7 @@ if module and enabled(name): yield name, module + def find(name): '''return module with given extension name''' mod = None @@ -75,6 +77,7 @@ raise KeyError(name) return mod + def loadpath(path, module_name): module_name = module_name.replace('.', '_') path = util.normpath(util.expandpath(path)) @@ -90,9 +93,10 @@ return imp.load_source(module_name, path) except IOError as exc: if not exc.filename: - exc.filename = path # python does not fill this + exc.filename = path # python does not fill this raise + def _importh(name): """import and return the <name> module""" mod = __import__(pycompat.sysstr(name)) @@ -101,6 +105,7 @@ mod = getattr(mod, comp) return mod + def _importext(name, path=None, reportfunc=None): if path: # the module will be loaded in sys.modules @@ -121,14 +126,21 @@ mod = _importh(name) return mod + def _reportimporterror(ui, err, failed, next): # note: this ui.log happens before --debug is processed, # Use --config ui.debug=1 to see them. - ui.log(b'extension', b' - could not import %s (%s): trying %s\n', - failed, stringutil.forcebytestr(err), next) + ui.log( + b'extension', + b' - could not import %s (%s): trying %s\n', + failed, + stringutil.forcebytestr(err), + next, + ) if ui.debugflag and ui.configbool('devel', 'debug.extensions'): ui.traceback() + def _rejectunicode(name, xs): if isinstance(xs, (list, set, tuple)): for x in xs: @@ -138,12 +150,16 @@ _rejectunicode(name, k) _rejectunicode(b'%s.%s' % (name, stringutil.forcebytestr(k)), v) elif isinstance(xs, type(u'')): - raise error.ProgrammingError(b"unicode %r found in %s" % (xs, name), - hint="use b'' to make it byte string") + raise error.ProgrammingError( + b"unicode %r found in %s" % (xs, name), + hint="use b'' to make it byte string", + ) + # attributes set by registrar.command _cmdfuncattrs = ('norepo', 'optionalrepo', 'inferrepo') + def _validatecmdtable(ui, cmdtable): """Check if extension commands have required attributes""" for c, e in cmdtable.iteritems(): @@ -153,19 +169,28 @@ continue raise error.ProgrammingError( 'missing attributes: %s' % ', '.join(missing), - hint="use @command decorator to register '%s'" % c) + hint="use @command decorator to register '%s'" % c, + ) + def _validatetables(ui, mod): """Sanity check for loadable tables provided by extension module""" for t in ['cmdtable', 'colortable', 'configtable']: _rejectunicode(t, getattr(mod, t, {})) - for t in ['filesetpredicate', 'internalmerge', 'revsetpredicate', - 'templatefilter', 'templatefunc', 'templatekeyword']: + for t in [ + 'filesetpredicate', + 'internalmerge', + 'revsetpredicate', + 'templatefilter', + 'templatefunc', + 'templatekeyword', + ]: o = getattr(mod, t, None) if o: _rejectunicode(t, o._table) _validatecmdtable(ui, getattr(mod, 'cmdtable', {})) + def load(ui, name, path, loadingtime=None): if name.startswith('hgext.') or name.startswith('hgext/'): shortname = name[6:] @@ -189,8 +214,10 @@ # of Mercurial. minver = getattr(mod, 'minimumhgversion', None) if minver and util.versiontuple(minver, 2) > util.versiontuple(n=2): - msg = _('(third party extension %s requires version %s or newer ' - 'of Mercurial (current: %s); disabling)\n') + msg = _( + '(third party extension %s requires version %s or newer ' + 'of Mercurial (current: %s); disabling)\n' + ) ui.warn(msg % (shortname, minver, util.version())) return ui.log(b'extension', b' - validating extension tables: %s\n', shortname) @@ -198,14 +225,16 @@ _extensions[shortname] = mod _order.append(shortname) - ui.log(b'extension', b' - invoking registered callbacks: %s\n', - shortname) + ui.log( + b'extension', b' - invoking registered callbacks: %s\n', shortname + ) with util.timedcm('callbacks extension %s', shortname) as stats: for fn in _aftercallbacks.get(shortname, []): fn(loaded=True) ui.log(b'extension', b' > callbacks completed in %s\n', stats) return mod + def _runuisetup(name, ui): uisetup = getattr(_extensions[name], 'uisetup', None) if uisetup: @@ -218,6 +247,7 @@ return False return True + def _runextsetup(name, ui): extsetup = getattr(_extensions[name], 'extsetup', None) if extsetup: @@ -230,22 +260,29 @@ return False return True + def loadall(ui, whitelist=None): loadingtime = collections.defaultdict(int) result = ui.configitems("extensions") if whitelist is not None: result = [(k, v) for (k, v) in result if k in whitelist] newindex = len(_order) - ui.log(b'extension', b'loading %sextensions\n', - 'additional ' if newindex else '') + ui.log( + b'extension', + b'loading %sextensions\n', + 'additional ' if newindex else '', + ) ui.log(b'extension', b'- processing %d entries\n', len(result)) with util.timedcm('load all extensions') as stats: for (name, path) in result: if path: if path[0:1] == '!': if name not in _disabledextensions: - ui.log(b'extension', - b' - skipping disabled extension: %s\n', name) + ui.log( + b'extension', + b' - skipping disabled extension: %s\n', + name, + ) _disabledextensions[name] = path[1:] continue try: @@ -253,17 +290,25 @@ except Exception as inst: msg = stringutil.forcebytestr(inst) if path: - ui.warn(_("*** failed to import extension %s from %s: %s\n") - % (name, path, msg)) + ui.warn( + _("*** failed to import extension %s from %s: %s\n") + % (name, path, msg) + ) else: - ui.warn(_("*** failed to import extension %s: %s\n") - % (name, msg)) + ui.warn( + _("*** failed to import extension %s: %s\n") + % (name, msg) + ) if isinstance(inst, error.Hint) and inst.hint: ui.warn(_("*** (%s)\n") % inst.hint) ui.traceback() - ui.log(b'extension', b'> loaded %d extensions, total time %s\n', - len(_order) - newindex, stats) + ui.log( + b'extension', + b'> loaded %d extensions, total time %s\n', + len(_order) - newindex, + stats, + ) # list of (objname, loadermod, loadername) tuple: # - objname is the name of an object in extension module, # from which extra information is loaded @@ -286,8 +331,11 @@ ui.log(b'extension', b' - running uisetup for %s\n', name) with util.timedcm('uisetup %s', name) as stats: if not _runuisetup(name, ui): - ui.log(b'extension', - b' - the %s extension uisetup failed\n', name) + ui.log( + b'extension', + b' - the %s extension uisetup failed\n', + name, + ) broken.add(name) ui.log(b'extension', b' > uisetup for %s took %s\n', name, stats) loadingtime[name] += stats.elapsed @@ -301,8 +349,11 @@ ui.log(b'extension', b' - running extsetup for %s\n', name) with util.timedcm('extsetup %s', name) as stats: if not _runextsetup(name, ui): - ui.log(b'extension', - b' - the %s extension extsetup failed\n', name) + ui.log( + b'extension', + b' - the %s extension extsetup failed\n', + name, + ) broken.add(name) ui.log(b'extension', b' > extsetup for %s took %s\n', name, stats) loadingtime[name] += stats.elapsed @@ -320,9 +371,11 @@ continue for fn in _aftercallbacks[shortname]: - ui.log(b'extension', - b' - extension %s not loaded, notify callbacks\n', - shortname) + ui.log( + b'extension', + b' - extension %s not loaded, notify callbacks\n', + shortname, + ) fn(loaded=False) ui.log(b'extension', b'> remaining aftercallbacks completed in %s\n', stats) @@ -361,27 +414,36 @@ ] with util.timedcm('load registration objects') as stats: _loadextra(ui, newindex, extraloaders) - ui.log(b'extension', b'> extension registration object loading took %s\n', - stats) + ui.log( + b'extension', + b'> extension registration object loading took %s\n', + stats, + ) # Report per extension loading time (except reposetup) for name in sorted(loadingtime): - ui.log(b'extension', b'> extension %s take a total of %s to load\n', - name, util.timecount(loadingtime[name])) + ui.log( + b'extension', + b'> extension %s take a total of %s to load\n', + name, + util.timecount(loadingtime[name]), + ) ui.log(b'extension', b'extension loading complete\n') + def _loadextra(ui, newindex, extraloaders): for name in _order[newindex:]: module = _extensions[name] if not module: - continue # loading this module failed + continue # loading this module failed for objname, loadermod, loadername in extraloaders: extraobj = getattr(module, objname, None) if extraobj is not None: getattr(loadermod, loadername)(ui, name, extraobj) + def afterloaded(extension, callback): '''Run the specified function after a named extension is loaded. @@ -397,11 +459,12 @@ if extension in _extensions: # Report loaded as False if the extension is disabled - loaded = (_extensions[extension] is not None) + loaded = _extensions[extension] is not None callback(loaded=loaded) else: _aftercallbacks.setdefault(extension, []).append(callback) + def populateui(ui): """Run extension hooks on the given ui to populate additional members, extend the class dynamically, etc. @@ -418,8 +481,11 @@ hook(ui) except Exception as inst: ui.traceback(force=True) - ui.warn(_('*** failed to populate ui by extension %s: %s\n') - % (name, stringutil.forcebytestr(inst))) + ui.warn( + _('*** failed to populate ui by extension %s: %s\n') + % (name, stringutil.forcebytestr(inst)) + ) + def bind(func, *args): '''Partial function application @@ -429,10 +495,13 @@ f(1, 2, bar=3) === bind(f, 1)(2, bar=3)''' assert callable(func) + def closure(*a, **kw): return func(*(args + a), **kw) + return closure + def _updatewrapper(wrap, origfn, unboundwrapper): '''Copy and add some useful attributes to wrapper''' try: @@ -445,6 +514,7 @@ wrap._origfunc = origfn wrap._unboundwrapper = unboundwrapper + def wrapcommand(table, command, wrapper, synopsis=None, docstring=None): '''Wrap the command named `command' in table @@ -482,8 +552,9 @@ break origfn = entry[0] - wrap = functools.partial(util.checksignature(wrapper), - util.checksignature(origfn)) + wrap = functools.partial( + util.checksignature(wrapper), util.checksignature(origfn) + ) _updatewrapper(wrap, origfn, wrapper) if docstring is not None: wrap.__doc__ += docstring @@ -495,6 +566,7 @@ table[key] = tuple(newentry) return entry + def wrapfilecache(cls, propname, wrapper): """Wraps a filecache property. @@ -506,14 +578,18 @@ if propname in currcls.__dict__: origfn = currcls.__dict__[propname].func assert callable(origfn) + def wrap(*args, **kwargs): return wrapper(origfn, *args, **kwargs) + currcls.__dict__[propname].func = wrap break if currcls is object: - raise AttributeError(r"type '%s' has no property '%s'" % ( - cls, propname)) + raise AttributeError( + r"type '%s' has no property '%s'" % (cls, propname) + ) + class wrappedfunction(object): '''context manager for temporarily wrapping a function''' @@ -530,6 +606,7 @@ def __exit__(self, exctype, excvalue, traceback): unwrapfunction(self._container, self._funcname, self._wrapper) + def wrapfunction(container, funcname, wrapper): '''Wrap the function named funcname in container @@ -579,6 +656,7 @@ setattr(container, funcname, wrap) return origfn + def unwrapfunction(container, funcname, wrapper=None): '''undo wrapfunction @@ -599,6 +677,7 @@ wrapfunction(container, funcname, w) return wrapper + def getwrapperchain(container, funcname): '''get a chain of wrappers of a function @@ -615,12 +694,15 @@ fn = getattr(fn, '_origfunc', None) return result + def _disabledpaths(): '''find paths of disabled extensions. returns a dict of {name: path}''' import hgext + extpath = os.path.dirname( - os.path.abspath(pycompat.fsencode(hgext.__file__))) - try: # might not be a filesystem path + os.path.abspath(pycompat.fsencode(hgext.__file__)) + ) + try: # might not be a filesystem path files = os.listdir(extpath) except OSError: return {} @@ -645,6 +727,7 @@ exts[name] = path return exts + def _moduledoc(file): '''return the top-level python documentation for the given file @@ -669,7 +752,7 @@ result.append(line) break elif not line: - return None # unmatched delimiter + return None # unmatched delimiter result.append(line) line = file.readline() else: @@ -677,6 +760,7 @@ return ''.join(result) + def _disabledhelp(path): '''retrieve help synopsis of a disabled extension (without importing)''' try: @@ -685,18 +769,22 @@ except IOError: return - if doc: # extracting localized synopsis + if doc: # extracting localized synopsis return gettext(doc) else: return _('(no help text available)') + def disabled(): '''find disabled extensions from hgext. returns a dict of {name: desc}''' try: from hgext import __index__ - return dict((name, gettext(desc)) - for name, desc in __index__.docs.iteritems() - if name not in _order) + + return dict( + (name, gettext(desc)) + for name, desc in __index__.docs.iteritems() + if name not in _order + ) except (ImportError, AttributeError): pass @@ -712,10 +800,12 @@ return exts + def disabledext(name): '''find a specific disabled extension from hgext. returns desc''' try: from hgext import __index__ + if name in _order: # enabled return else: @@ -727,6 +817,7 @@ if name in paths: return _disabledhelp(paths[name]) + def _walkcommand(node): """Scan @command() decorators in the tree starting at node""" todo = collections.deque([node]) @@ -744,6 +835,7 @@ continue yield d + def _disabledcmdtable(path): """Construct a dummy command table without loading the extension module @@ -765,6 +857,7 @@ cmdtable[name] = (None, [], b'') return cmdtable + def _finddisabledcmd(ui, cmd, name, path, strict): try: cmdtable = _disabledcmdtable(path) @@ -783,6 +876,7 @@ doc = _disabledhelp(path) return (cmd, name, doc) + def disabledcmd(ui, cmd, strict=False): '''find cmd from disabled extensions without importing. returns (cmdname, extname, doc)''' @@ -807,25 +901,27 @@ raise error.UnknownCommand(cmd) + def enabled(shortname=True): '''return a dict of {name: desc} of extensions''' exts = {} for ename, ext in extensions(): - doc = (gettext(ext.__doc__) or _('(no help text available)')) + doc = gettext(ext.__doc__) or _('(no help text available)') if shortname: ename = ename.split('.')[-1] exts[ename] = doc.splitlines()[0].strip() return exts + def notloaded(): '''return short names of extensions that failed to load''' return [name for name, mod in _extensions.iteritems() if mod is None] + def moduleversion(module): '''return version information from given module as a string''' - if (util.safehasattr(module, 'getversion') - and callable(module.getversion)): + if util.safehasattr(module, 'getversion') and callable(module.getversion): version = module.getversion() elif util.safehasattr(module, '__version__'): version = module.__version__ @@ -835,6 +931,7 @@ version = '.'.join(pycompat.bytestr(o) for o in version) return version + def ismoduleinternal(module): exttestedwith = getattr(module, 'testedwith', None) return exttestedwith == "ships-with-hg-core"