codemod: register core configitems using a script
authorJun Wu <quark@fb.com>
Fri, 14 Jul 2017 14:22:40 -0700
changeset 33499 0407a51b9d8c
parent 33498 b7a75b9a3386
child 33500 9c6e64911de0
codemod: register core configitems using a script This is done by a script [2] using RedBaron [1], a tool designed for doing code refactoring. All "default" values are decided by the script and are strongly consistent with the existing code. There are 2 changes done manually to fix tests: [warn] mercurial/exchange.py: experimental.bundle2-output-capture: default needs manual removal [warn] mercurial/localrepo.py: experimental.hook-track-tags: default needs manual removal Since RedBaron is not confident about how to indent things [2]. [1]: https://github.com/PyCQA/redbaron [2]: https://github.com/PyCQA/redbaron/issues/100 [3]: #!/usr/bin/env python # codemod_configitems.py - codemod tool to fill configitems # # Copyright 2017 Facebook, Inc. # # This software may be used and distributed according to the terms of the # GNU General Public License version 2 or any later version. from __future__ import absolute_import, print_function import os import sys import redbaron def readpath(path): with open(path) as f: return f.read() def writepath(path, content): with open(path, 'w') as f: f.write(content) _configmethods = {'config', 'configbool', 'configint', 'configbytes', 'configlist', 'configdate'} def extractstring(rnode): """get the string from a RedBaron string or call_argument node""" while rnode.type != 'string': rnode = rnode.value return rnode.value[1:-1] # unquote, "'str'" -> "str" def uiconfigitems(red): """match *.ui.config* pattern, yield (node, method, args, section, name)""" for node in red.find_all('atomtrailers'): entry = None try: obj = node[-3].value method = node[-2].value args = node[-1] section = args[0].value name = args[1].value if (obj in ('ui', 'self') and method in _configmethods and section.type == 'string' and name.type == 'string'): entry = (node, method, args, extractstring(section), extractstring(name)) except Exception: pass else: if entry: yield entry def coreconfigitems(red): """match coreconfigitem(...) pattern, yield (node, args, section, name)""" for node in red.find_all('atomtrailers'): entry = None try: args = node[1] section = args[0].value name = args[1].value if (node[0].value == 'coreconfigitem' and section.type == 'string' and name.type == 'string'): entry = (node, args, extractstring(section), extractstring(name)) except Exception: pass else: if entry: yield entry def registercoreconfig(cfgred, section, name, defaultrepr): """insert coreconfigitem to cfgred AST section and name are plain string, defaultrepr is a string """ # find a place to insert the "coreconfigitem" item entries = list(coreconfigitems(cfgred)) for node, args, nodesection, nodename in reversed(entries): if (nodesection, nodename) < (section, name): # insert after this entry node.insert_after( 'coreconfigitem(%r, %r,\n' ' default=%s,\n' ')' % (section, name, defaultrepr)) return def main(argv): if not argv: print('Usage: codemod_configitems.py FILES\n' 'For example, FILES could be "{hgext,mercurial}/*/**.py"') dirname = os.path.dirname reporoot = dirname(dirname(dirname(os.path.abspath(__file__)))) # register configitems to this destination cfgpath = os.path.join(reporoot, 'mercurial', 'configitems.py') cfgred = redbaron.RedBaron(readpath(cfgpath)) # state about what to do registered = set((s, n) for n, a, s, n in coreconfigitems(cfgred)) toregister = {} # {(section, name): defaultrepr} coreconfigs = set() # {(section, name)}, whether it's used in core # first loop: scan all files before taking any action for i, path in enumerate(argv): print('(%d/%d) scanning %s' % (i + 1, len(argv), path)) iscore = ('mercurial' in path) and ('hgext' not in path) red = redbaron.RedBaron(readpath(path)) # find all repo.ui.config* and ui.config* calls, and collect their # section, name and default value information. for node, method, args, section, name in uiconfigitems(red): if section == 'web': # [web] section has some weirdness, ignore them for now continue defaultrepr = None key = (section, name) if len(args) == 2: if key in registered: continue if method == 'configlist': defaultrepr = 'list' elif method == 'configbool': defaultrepr = 'False' else: defaultrepr = 'None' elif len(args) >= 3 and (args[2].target is None or args[2].target.value == 'default'): # try to understand the "default" value dnode = args[2].value if dnode.type == 'name': if dnode.value in {'None', 'True', 'False'}: defaultrepr = dnode.value elif dnode.type == 'string': defaultrepr = repr(dnode.value[1:-1]) elif dnode.type in ('int', 'float'): defaultrepr = dnode.value # inconsistent default if key in toregister and toregister[key] != defaultrepr: defaultrepr = None # interesting to rewrite if key not in registered: if defaultrepr is None: print('[note] %s: %s.%s: unsupported default' % (path, section, name)) registered.add(key) # skip checking it again else: toregister[key] = defaultrepr if iscore: coreconfigs.add(key) # second loop: rewrite files given "toregister" result for path in argv: # reconstruct redbaron - trade CPU for memory red = redbaron.RedBaron(readpath(path)) changed = False for node, method, args, section, name in uiconfigitems(red): key = (section, name) defaultrepr = toregister.get(key) if defaultrepr is None or key not in coreconfigs: continue if len(args) >= 3 and (args[2].target is None or args[2].target.value == 'default'): try: del args[2] changed = True except Exception: # redbaron fails to do the rewrite due to indentation # see https://github.com/PyCQA/redbaron/issues/100 print('[warn] %s: %s.%s: default needs manual removal' % (path, section, name)) if key not in registered: print('registering %s.%s' % (section, name)) registercoreconfig(cfgred, section, name, defaultrepr) registered.add(key) if changed: print('updating %s' % path) writepath(path, red.dumps()) if toregister: print('updating configitems.py') writepath(cfgpath, cfgred.dumps()) if __name__ == "__main__": sys.exit(main(sys.argv[1:]))
hgext/journal.py
hgext/largefiles/overrides.py
mercurial/archival.py
mercurial/bookmarks.py
mercurial/bundle2.py
mercurial/chgserver.py
mercurial/cmdutil.py
mercurial/commands.py
mercurial/commandserver.py
mercurial/configitems.py
mercurial/context.py
mercurial/dispatch.py
mercurial/exchange.py
mercurial/filemerge.py
mercurial/help.py
mercurial/httpconnection.py
mercurial/httppeer.py
mercurial/localrepo.py
mercurial/mail.py
mercurial/merge.py
mercurial/obsolete.py
mercurial/profiling.py
mercurial/progress.py
mercurial/scmutil.py
mercurial/sparse.py
mercurial/sshpeer.py
mercurial/streamclone.py
mercurial/subrepo.py
mercurial/ui.py
mercurial/url.py
mercurial/verify.py
mercurial/wireproto.py
--- a/hgext/journal.py	Tue Jul 11 08:52:55 2017 -0700
+++ b/hgext/journal.py	Fri Jul 14 14:22:40 2017 -0700
@@ -303,7 +303,7 @@
             # default to 600 seconds timeout
             l = lock.lock(
                 vfs, 'namejournal.lock',
-                int(self.ui.config("ui", "timeout", "600")), desc=desc)
+                int(self.ui.config("ui", "timeout")), desc=desc)
             self.ui.warn(_("got lock after %s seconds\n") % l.delay)
         self._lockref = weakref.ref(l)
         return l
--- a/hgext/largefiles/overrides.py	Tue Jul 11 08:52:55 2017 -0700
+++ b/hgext/largefiles/overrides.py	Fri Jul 14 14:22:40 2017 -0700
@@ -973,7 +973,7 @@
 
     archiver = archival.archivers[kind](dest, mtime or ctx.date()[0])
 
-    if repo.ui.configbool("ui", "archivemeta", True):
+    if repo.ui.configbool("ui", "archivemeta"):
         write('.hg_archival.txt', 0o644, False,
               lambda: archival.buildmetadata(ctx))
 
--- a/mercurial/archival.py	Tue Jul 11 08:52:55 2017 -0700
+++ b/mercurial/archival.py	Fri Jul 14 14:22:40 2017 -0700
@@ -307,7 +307,7 @@
     ctx = repo[node]
     archiver = archivers[kind](dest, mtime or ctx.date()[0])
 
-    if repo.ui.configbool("ui", "archivemeta", True):
+    if repo.ui.configbool("ui", "archivemeta"):
         name = '.hg_archival.txt'
         if not matchfn or matchfn(name):
             write(name, 0o644, False, lambda: buildmetadata(ctx))
--- a/mercurial/bookmarks.py	Tue Jul 11 08:52:55 2017 -0700
+++ b/mercurial/bookmarks.py	Fri Jul 14 14:22:40 2017 -0700
@@ -533,7 +533,7 @@
 
     status = ui.status
     warn = ui.warn
-    if ui.configbool('ui', 'quietbookmarkmove', False):
+    if ui.configbool('ui', 'quietbookmarkmove'):
         status = warn = ui.debug
 
     explicit = set(explicit)
--- a/mercurial/bundle2.py	Tue Jul 11 08:52:55 2017 -0700
+++ b/mercurial/bundle2.py	Fri Jul 14 14:22:40 2017 -0700
@@ -1801,7 +1801,7 @@
     """add a stream of obsmarkers to the repo"""
     tr = op.gettransaction()
     markerdata = inpart.read()
-    if op.ui.config('experimental', 'obsmarkers-exchange-debug', False):
+    if op.ui.config('experimental', 'obsmarkers-exchange-debug'):
         op.ui.write(('obsmarker-exchange: %i bytes received\n')
                     % len(markerdata))
     # The mergemarkers call will crash if marker creation is not enabled.
--- a/mercurial/chgserver.py	Tue Jul 11 08:52:55 2017 -0700
+++ b/mercurial/chgserver.py	Fri Jul 14 14:22:40 2017 -0700
@@ -485,7 +485,7 @@
 
     def __init__(self, ui):
         self.ui = ui
-        self._idletimeout = ui.configint('chgserver', 'idletimeout', 3600)
+        self._idletimeout = ui.configint('chgserver', 'idletimeout')
         self._lastactive = time.time()
 
     def bindsocket(self, sock, address):
@@ -497,7 +497,7 @@
 
     def _inithashstate(self, address):
         self._baseaddress = address
-        if self.ui.configbool('chgserver', 'skiphash', False):
+        if self.ui.configbool('chgserver', 'skiphash'):
             self._hashstate = None
             self._realaddress = address
             return
--- a/mercurial/cmdutil.py	Tue Jul 11 08:52:55 2017 -0700
+++ b/mercurial/cmdutil.py	Fri Jul 14 14:22:40 2017 -0700
@@ -208,7 +208,7 @@
     (see patch.filterpatch).
     """
     usecurses = crecordmod.checkcurses(ui)
-    testfile = ui.config('experimental', 'crecordtest', None)
+    testfile = ui.config('experimental', 'crecordtest')
     oldwrite = setupwrapcolorwrite(ui)
     try:
         newchunks, newopts = filterchunks(ui, originalhunks, usecurses,
@@ -1687,7 +1687,7 @@
         if tmpl:
             return logtemplatespec(templater.unquotestring(tmpl), None)
         else:
-            style = util.expandpath(ui.config('ui', 'style', ''))
+            style = util.expandpath(ui.config('ui', 'style'))
 
     if not tmpl and style:
         mapfile = style
@@ -3406,8 +3406,7 @@
         if node != parent:
             operation = 'revert'
             reversehunks = repo.ui.configbool('experimental',
-                                              'revertalternateinteractivemode',
-                                              True)
+                'revertalternateinteractivemode')
         if reversehunks:
             diff = patch.diff(repo, ctx.node(), None, m, opts=diffopts)
         else:
--- a/mercurial/commands.py	Tue Jul 11 08:52:55 2017 -0700
+++ b/mercurial/commands.py	Fri Jul 14 14:22:40 2017 -0700
@@ -1227,9 +1227,9 @@
 
 
     contentopts = {'cg.version': cgversion}
-    if repo.ui.configbool('experimental', 'evolution.bundle-obsmarker', False):
+    if repo.ui.configbool('experimental', 'evolution.bundle-obsmarker'):
         contentopts['obsolescence'] = True
-    if repo.ui.configbool('experimental', 'bundle-phases', False):
+    if repo.ui.configbool('experimental', 'bundle-phases'):
         contentopts['phases'] = True
     bundle2.writenewbundle(ui, repo, 'bundle', fname, bversion, outgoing,
                            contentopts, compression=bcompression,
@@ -4524,7 +4524,7 @@
 
     Returns 0 on success, 1 if no rollback data is available.
     """
-    if not ui.configbool('ui', 'rollback', True):
+    if not ui.configbool('ui', 'rollback'):
         raise error.Abort(_('rollback is disabled because it is unsafe'),
                           hint=('see `hg help -v rollback` for information'))
     return repo.rollback(dryrun=opts.get(r'dry_run'),
--- a/mercurial/commandserver.py	Tue Jul 11 08:52:55 2017 -0700
+++ b/mercurial/commandserver.py	Fri Jul 14 14:22:40 2017 -0700
@@ -156,7 +156,7 @@
         self.cwd = pycompat.getcwd()
 
         # developer config: cmdserver.log
-        logpath = ui.config("cmdserver", "log", None)
+        logpath = ui.config("cmdserver", "log")
         if logpath:
             global logfile
             if logpath == '-':
--- a/mercurial/configitems.py	Tue Jul 11 08:52:55 2017 -0700
+++ b/mercurial/configitems.py	Fri Jul 14 14:22:40 2017 -0700
@@ -76,12 +76,30 @@
 coreconfigitem('bundle', 'reorder',
     default='auto',
 )
+coreconfigitem('censor', 'policy',
+    default='abort',
+)
+coreconfigitem('chgserver', 'idletimeout',
+    default=3600,
+)
+coreconfigitem('chgserver', 'skiphash',
+    default=False,
+)
+coreconfigitem('cmdserver', 'log',
+    default=None,
+)
 coreconfigitem('color', 'mode',
     default='auto',
 )
 coreconfigitem('color', 'pagermode',
     default=dynamicdefault,
 )
+coreconfigitem('commands', 'status.relative',
+    default=False,
+)
+coreconfigitem('commands', 'update.requiredest',
+    default=False,
+)
 coreconfigitem('devel', 'all-warnings',
     default=False,
 )
@@ -94,6 +112,12 @@
 coreconfigitem('devel', 'check-relroot',
     default=False,
 )
+coreconfigitem('devel', 'default-date',
+    default=None,
+)
+coreconfigitem('devel', 'deprec-warn',
+    default=False,
+)
 coreconfigitem('devel', 'disableloaddefaultcerts',
     default=False,
 )
@@ -112,6 +136,99 @@
 coreconfigitem('devel', 'strip-obsmarkers',
     default=True,
 )
+coreconfigitem('email', 'charsets',
+    default=list,
+)
+coreconfigitem('email', 'method',
+    default='smtp',
+)
+coreconfigitem('experimental', 'bundle-phases',
+    default=False,
+)
+coreconfigitem('experimental', 'bundle2-advertise',
+    default=True,
+)
+coreconfigitem('experimental', 'bundle2-output-capture',
+    default=False,
+)
+coreconfigitem('experimental', 'bundle2.pushback',
+    default=False,
+)
+coreconfigitem('experimental', 'bundle2lazylocking',
+    default=False,
+)
+coreconfigitem('experimental', 'bundlecomplevel',
+    default=None,
+)
+coreconfigitem('experimental', 'changegroup3',
+    default=False,
+)
+coreconfigitem('experimental', 'clientcompressionengines',
+    default=list,
+)
+coreconfigitem('experimental', 'crecordtest',
+    default=None,
+)
+coreconfigitem('experimental', 'disablecopytrace',
+    default=False,
+)
+coreconfigitem('experimental', 'editortmpinhg',
+    default=False,
+)
+coreconfigitem('experimental', 'evolution',
+    default=list,
+)
+coreconfigitem('experimental', 'evolution.bundle-obsmarker',
+    default=False,
+)
+coreconfigitem('experimental', 'evolution.track-operation',
+    default=False,
+)
+coreconfigitem('experimental', 'exportableenviron',
+    default=list,
+)
+coreconfigitem('experimental', 'extendedheader.index',
+    default=None,
+)
+coreconfigitem('experimental', 'extendedheader.similarity',
+    default=False,
+)
+coreconfigitem('experimental', 'format.compression',
+    default='zlib',
+)
+coreconfigitem('experimental', 'graphshorten',
+    default=False,
+)
+coreconfigitem('experimental', 'hook-track-tags',
+    default=False,
+)
+coreconfigitem('experimental', 'httppostargs',
+    default=False,
+)
+coreconfigitem('experimental', 'manifestv2',
+    default=False,
+)
+coreconfigitem('experimental', 'mergedriver',
+    default=None,
+)
+coreconfigitem('experimental', 'obsmarkers-exchange-debug',
+    default=False,
+)
+coreconfigitem('experimental', 'revertalternateinteractivemode',
+    default=True,
+)
+coreconfigitem('experimental', 'revlogv2',
+    default=None,
+)
+coreconfigitem('experimental', 'spacemovesdown',
+    default=False,
+)
+coreconfigitem('experimental', 'treemanifest',
+    default=False,
+)
+coreconfigitem('experimental', 'updatecheck',
+    default=None,
+)
 coreconfigitem('format', 'aggressivemergedeltas',
     default=False,
 )
@@ -148,21 +265,90 @@
 coreconfigitem('hostsecurity', 'disabletls10warning',
     default=False,
 )
+coreconfigitem('http_proxy', 'always',
+    default=False,
+)
+coreconfigitem('http_proxy', 'host',
+    default=None,
+)
+coreconfigitem('http_proxy', 'no',
+    default=list,
+)
+coreconfigitem('http_proxy', 'passwd',
+    default=None,
+)
+coreconfigitem('http_proxy', 'user',
+    default=None,
+)
+coreconfigitem('merge', 'followcopies',
+    default=True,
+)
+coreconfigitem('pager', 'ignore',
+    default=list,
+)
 coreconfigitem('patch', 'eol',
     default='strict',
 )
 coreconfigitem('patch', 'fuzz',
     default=2,
 )
+coreconfigitem('paths', 'default',
+    default=None,
+)
+coreconfigitem('paths', 'default-push',
+    default=None,
+)
+coreconfigitem('phases', 'checksubrepos',
+    default='follow',
+)
+coreconfigitem('phases', 'publish',
+    default=True,
+)
+coreconfigitem('profiling', 'enabled',
+    default=False,
+)
+coreconfigitem('profiling', 'format',
+    default='text',
+)
+coreconfigitem('profiling', 'freq',
+    default=1000,
+)
+coreconfigitem('profiling', 'limit',
+    default=30,
+)
+coreconfigitem('profiling', 'nested',
+    default=0,
+)
+coreconfigitem('profiling', 'sort',
+    default='inlinetime',
+)
+coreconfigitem('profiling', 'statformat',
+    default='hotpath',
+)
 coreconfigitem('progress', 'assume-tty',
     default=False,
 )
+coreconfigitem('progress', 'changedelay',
+    default=1,
+)
 coreconfigitem('progress', 'clear-complete',
     default=True,
 )
+coreconfigitem('progress', 'debug',
+    default=False,
+)
+coreconfigitem('progress', 'delay',
+    default=3,
+)
+coreconfigitem('progress', 'disable',
+    default=False,
+)
 coreconfigitem('progress', 'estimate',
     default=2,
 )
+coreconfigitem('progress', 'refresh',
+    default=0.1,
+)
 coreconfigitem('progress', 'width',
     default=dynamicdefault,
 )
@@ -187,6 +373,9 @@
 coreconfigitem('server', 'preferuncompressed',
     default=False,
 )
+coreconfigitem('server', 'uncompressed',
+    default=True,
+)
 coreconfigitem('server', 'uncompressedallowsecret',
     default=False,
 )
@@ -196,18 +385,171 @@
 coreconfigitem('server', 'zliblevel',
     default=-1,
 )
+coreconfigitem('smtp', 'host',
+    default=None,
+)
+coreconfigitem('smtp', 'local_hostname',
+    default=None,
+)
+coreconfigitem('smtp', 'password',
+    default=None,
+)
+coreconfigitem('smtp', 'tls',
+    default='none',
+)
+coreconfigitem('smtp', 'username',
+    default=None,
+)
+coreconfigitem('sparse', 'missingwarning',
+    default=True,
+)
+coreconfigitem('trusted', 'groups',
+    default=list,
+)
+coreconfigitem('trusted', 'users',
+    default=list,
+)
+coreconfigitem('ui', '_usedassubrepo',
+    default=False,
+)
+coreconfigitem('ui', 'allowemptycommit',
+    default=False,
+)
+coreconfigitem('ui', 'archivemeta',
+    default=True,
+)
+coreconfigitem('ui', 'askusername',
+    default=False,
+)
+coreconfigitem('ui', 'clonebundlefallback',
+    default=False,
+)
 coreconfigitem('ui', 'clonebundleprefers',
     default=list,
 )
+coreconfigitem('ui', 'clonebundles',
+    default=True,
+)
+coreconfigitem('ui', 'commitsubrepos',
+    default=False,
+)
+coreconfigitem('ui', 'debug',
+    default=False,
+)
+coreconfigitem('ui', 'debugger',
+    default=None,
+)
+coreconfigitem('ui', 'forcemerge',
+    default=None,
+)
+coreconfigitem('ui', 'formatdebug',
+    default=False,
+)
+coreconfigitem('ui', 'formatjson',
+    default=False,
+)
+coreconfigitem('ui', 'formatted',
+    default=None,
+)
+coreconfigitem('ui', 'graphnodetemplate',
+    default=None,
+)
+coreconfigitem('ui', 'http2debuglevel',
+    default=None,
+)
 coreconfigitem('ui', 'interactive',
     default=None,
 )
+coreconfigitem('ui', 'interface',
+    default=None,
+)
+coreconfigitem('ui', 'logblockedtimes',
+    default=False,
+)
+coreconfigitem('ui', 'logtemplate',
+    default=None,
+)
+coreconfigitem('ui', 'merge',
+    default=None,
+)
+coreconfigitem('ui', 'mergemarkers',
+    default='basic',
+)
+coreconfigitem('ui', 'nontty',
+    default=False,
+)
+coreconfigitem('ui', 'origbackuppath',
+    default=None,
+)
+coreconfigitem('ui', 'paginate',
+    default=True,
+)
+coreconfigitem('ui', 'patch',
+    default=None,
+)
+coreconfigitem('ui', 'portablefilenames',
+    default='warn',
+)
+coreconfigitem('ui', 'promptecho',
+    default=False,
+)
 coreconfigitem('ui', 'quiet',
     default=False,
 )
+coreconfigitem('ui', 'quietbookmarkmove',
+    default=False,
+)
+coreconfigitem('ui', 'remotecmd',
+    default='hg',
+)
+coreconfigitem('ui', 'report_untrusted',
+    default=True,
+)
+coreconfigitem('ui', 'rollback',
+    default=True,
+)
+coreconfigitem('ui', 'slash',
+    default=False,
+)
+coreconfigitem('ui', 'ssh',
+    default='ssh',
+)
+coreconfigitem('ui', 'statuscopies',
+    default=False,
+)
+coreconfigitem('ui', 'strict',
+    default=False,
+)
+coreconfigitem('ui', 'style',
+    default='',
+)
+coreconfigitem('ui', 'supportcontact',
+    default=None,
+)
+coreconfigitem('ui', 'textwidth',
+    default=78,
+)
+coreconfigitem('ui', 'timeout',
+    default='600',
+)
+coreconfigitem('ui', 'traceback',
+    default=False,
+)
+coreconfigitem('ui', 'tweakdefaults',
+    default=False,
+)
+coreconfigitem('ui', 'usehttp2',
+    default=False,
+)
 coreconfigitem('ui', 'username',
     alias=[('ui', 'user')]
 )
+coreconfigitem('ui', 'verbose',
+    default=False,
+)
+coreconfigitem('verify', 'skipflags',
+    default=None,
+)
 coreconfigitem('worker', 'backgroundclose',
     default=dynamicdefault,
 )
--- a/mercurial/context.py	Tue Jul 11 08:52:55 2017 -0700
+++ b/mercurial/context.py	Fri Jul 14 14:22:40 2017 -0700
@@ -1231,7 +1231,7 @@
         try:
             return self._filelog.read(self._filenode)
         except error.CensoredNodeError:
-            if self._repo.ui.config("censor", "policy", "abort") == "ignore":
+            if self._repo.ui.config("censor", "policy") == "ignore":
                 return ""
             raise error.Abort(_("censored node: %s") % short(self._filenode),
                              hint=_("set censor.policy to ignore errors"))
--- a/mercurial/dispatch.py	Tue Jul 11 08:52:55 2017 -0700
+++ b/mercurial/dispatch.py	Fri Jul 14 14:22:40 2017 -0700
@@ -916,7 +916,7 @@
     # version number and try updating.
     ct = util.versiontuple(n=2)
     worst = None, ct, ''
-    if ui.config('ui', 'supportcontact', None) is None:
+    if ui.config('ui', 'supportcontact') is None:
         for name, mod in extensions.extensions():
             testedwith = getattr(mod, 'testedwith', '')
             if pycompat.ispy3 and isinstance(testedwith, str):
@@ -950,7 +950,7 @@
                      '** If that fixes the bug please report it to %s\n')
                    % (name, testedwith, name, report))
     else:
-        bugtracker = ui.config('ui', 'supportcontact', None)
+        bugtracker = ui.config('ui', 'supportcontact')
         if bugtracker is None:
             bugtracker = _("https://mercurial-scm.org/wiki/BugTracker")
         warning = (_("** unknown exception encountered, "
--- a/mercurial/exchange.py	Tue Jul 11 08:52:55 2017 -0700
+++ b/mercurial/exchange.py	Fri Jul 14 14:22:40 2017 -0700
@@ -547,7 +547,7 @@
     unfi = pushop.repo.unfiltered()
     remotephases = pushop.remote.listkeys('phases')
     publishing = remotephases.get('publishing', False)
-    if (pushop.ui.configbool('ui', '_usedassubrepo', False)
+    if (pushop.ui.configbool('ui', '_usedassubrepo')
         and remotephases    # server supports phases
         and not pushop.outgoing.missing # no changesets to be pushed
         and publishing):
@@ -993,7 +993,7 @@
     cheads = pushop.commonheads
     # even when we don't push, exchanging phase data is useful
     remotephases = pushop.remote.listkeys('phases')
-    if (pushop.ui.configbool('ui', '_usedassubrepo', False)
+    if (pushop.ui.configbool('ui', '_usedassubrepo')
         and remotephases    # server supports phases
         and pushop.cgresult is None # nothing was pushed
         and remotephases.get('publishing', False)):
@@ -1726,8 +1726,7 @@
     lockandtr = [None, None, None]
     recordout = None
     # quick fix for output mismatch with bundle2 in 3.4
-    captureoutput = repo.ui.configbool('experimental', 'bundle2-output-capture',
-                                       False)
+    captureoutput = repo.ui.configbool('experimental', 'bundle2-output-capture')
     if url.startswith('remote:http:') or url.startswith('remote:https:'):
         captureoutput = True
     try:
@@ -1792,7 +1791,7 @@
     repo = pullop.repo
     remote = pullop.remote
 
-    if not repo.ui.configbool('ui', 'clonebundles', True):
+    if not repo.ui.configbool('ui', 'clonebundles'):
         return
 
     # Only run if local repo is empty.
@@ -1841,7 +1840,7 @@
     # We abort by default to avoid the thundering herd of
     # clients flooding a server that was expecting expensive
     # clone load to be offloaded.
-    elif repo.ui.configbool('ui', 'clonebundlefallback', False):
+    elif repo.ui.configbool('ui', 'clonebundlefallback'):
         repo.ui.warn(_('falling back to normal clone\n'))
     else:
         raise error.Abort(_('error applying bundle'),
--- a/mercurial/filemerge.py	Tue Jul 11 08:52:55 2017 -0700
+++ b/mercurial/filemerge.py	Fri Jul 14 14:22:40 2017 -0700
@@ -685,7 +685,7 @@
 
     r = 1
     try:
-        markerstyle = ui.config('ui', 'mergemarkers', 'basic')
+        markerstyle = ui.config('ui', 'mergemarkers')
         if not labels:
             labels = _defaultconflictlabels
         if markerstyle != 'basic':
--- a/mercurial/help.py	Tue Jul 11 08:52:55 2017 -0700
+++ b/mercurial/help.py	Fri Jul 14 14:22:40 2017 -0700
@@ -647,7 +647,7 @@
                 subtopic = remaining
             else:
                 section = remaining
-    textwidth = ui.configint('ui', 'textwidth', 78)
+    textwidth = ui.configint('ui', 'textwidth')
     termwidth = ui.termwidth() - 2
     if textwidth <= 0 or termwidth < textwidth:
         textwidth = termwidth
--- a/mercurial/httpconnection.py	Tue Jul 11 08:52:55 2017 -0700
+++ b/mercurial/httpconnection.py	Fri Jul 14 14:22:40 2017 -0700
@@ -141,7 +141,7 @@
         self.pwmgr = pwmgr
         self._connections = {}
         # developer config: ui.http2debuglevel
-        loglevel = ui.config('ui', 'http2debuglevel', default=None)
+        loglevel = ui.config('ui', 'http2debuglevel')
         if loglevel and not _configuredlogging:
             _configuredlogging = True
             logger = logging.getLogger('mercurial.httpclient')
--- a/mercurial/httppeer.py	Tue Jul 11 08:52:55 2017 -0700
+++ b/mercurial/httppeer.py	Fri Jul 14 14:22:40 2017 -0700
@@ -181,7 +181,7 @@
             size = data.length
         elif data is not None:
             size = len(data)
-        if size and self.ui.configbool('ui', 'usehttp2', False):
+        if size and self.ui.configbool('ui', 'usehttp2'):
             headers['Expect'] = '100-Continue'
             headers['X-HgHttp2'] = '1'
         if data is not None and 'Content-Type' not in headers:
--- a/mercurial/localrepo.py	Tue Jul 11 08:52:55 2017 -0700
+++ b/mercurial/localrepo.py	Fri Jul 14 14:22:40 2017 -0700
@@ -532,7 +532,7 @@
             self._revbranchcache.write()
 
     def _restrictcapabilities(self, caps):
-        if self.ui.configbool('experimental', 'bundle2-advertise', True):
+        if self.ui.configbool('experimental', 'bundle2-advertise'):
             caps = set(caps)
             capsblob = bundle2.encodecaps(bundle2.getrepocaps(self))
             caps.add('bundle2=' + urlreq.quote(capsblob))
@@ -951,7 +951,7 @@
     def publishing(self):
         # it's safe (and desirable) to trust the publish flag unconditionally
         # so that we don't finalize changes shared between users via ssh or nfs
-        return self.ui.configbool('phases', 'publish', True, untrusted=True)
+        return self.ui.configbool('phases', 'publish', untrusted=True)
 
     def cancopy(self):
         # so statichttprepo's override of local() works
@@ -1149,8 +1149,7 @@
         #   "+M": tag is moved (new value),
         tracktags = lambda x: None
         # experimental config: experimental.hook-track-tags
-        shouldtracktags = self.ui.configbool('experimental', 'hook-track-tags',
-                                             False)
+        shouldtracktags = self.ui.configbool('experimental', 'hook-track-tags')
         if desc != 'strip' and shouldtracktags:
             oldheads = self.changelog.headrevs()
             def tracktags(tr2):
@@ -1506,7 +1505,7 @@
                              (desc, inst.locker))
             # default to 600 seconds timeout
             l = lockmod.lock(vfs, lockname,
-                             int(self.ui.config("ui", "timeout", "600")),
+                             int(self.ui.config("ui", "timeout")),
                              releasefn=releasefn, acquirefn=acquirefn,
                              desc=desc)
             self.ui.warn(_("got lock after %s seconds\n") % l.delay)
@@ -2218,7 +2217,7 @@
             if ui.configbool('format', 'dotencode'):
                 requirements.add('dotencode')
 
-    compengine = ui.config('experimental', 'format.compression', 'zlib')
+    compengine = ui.config('experimental', 'format.compression')
     if compengine not in util.compengines:
         raise error.Abort(_('compression engine %s defined by '
                             'experimental.format.compression not available') %
@@ -2232,9 +2231,9 @@
 
     if scmutil.gdinitconfig(ui):
         requirements.add('generaldelta')
-    if ui.configbool('experimental', 'treemanifest', False):
+    if ui.configbool('experimental', 'treemanifest'):
         requirements.add('treemanifest')
-    if ui.configbool('experimental', 'manifestv2', False):
+    if ui.configbool('experimental', 'manifestv2'):
         requirements.add('manifestv2')
 
     revlogv2 = ui.config('experimental', 'revlogv2')
--- a/mercurial/mail.py	Tue Jul 11 08:52:55 2017 -0700
+++ b/mercurial/mail.py	Fri Jul 14 14:22:40 2017 -0700
@@ -78,7 +78,7 @@
 def _smtp(ui):
     '''build an smtp connection and return a function to send mail'''
     local_hostname = ui.config('smtp', 'local_hostname')
-    tls = ui.config('smtp', 'tls', 'none')
+    tls = ui.config('smtp', 'tls')
     # backward compatible: when tls = true, we use starttls.
     starttls = tls == 'starttls' or util.parsebool(tls)
     smtps = tls == 'smtps'
@@ -135,7 +135,7 @@
 
 def _sendmail(ui, sender, recipients, msg):
     '''send mail using sendmail.'''
-    program = ui.config('email', 'method', 'smtp')
+    program = ui.config('email', 'method')
     cmdline = '%s -f %s %s' % (program, util.email(sender),
                                ' '.join(map(util.email, recipients)))
     ui.note(_('sending mail: %s\n') % cmdline)
@@ -164,7 +164,7 @@
     if mbox:
         open(mbox, 'wb').close()
         return lambda s, r, m: _mbox(mbox, s, r, m)
-    if ui.config('email', 'method', 'smtp') == 'smtp':
+    if ui.config('email', 'method') == 'smtp':
         return _smtp(ui)
     return lambda s, r, m: _sendmail(ui, s, r, m)
 
@@ -174,7 +174,7 @@
 
 def validateconfig(ui):
     '''determine if we have enough config data to try sending email.'''
-    method = ui.config('email', 'method', 'smtp')
+    method = ui.config('email', 'method')
     if method == 'smtp':
         if not ui.config('smtp', 'host'):
             raise error.Abort(_('smtp specified as email transport, '
--- a/mercurial/merge.py	Tue Jul 11 08:52:55 2017 -0700
+++ b/mercurial/merge.py	Fri Jul 14 14:22:40 2017 -0700
@@ -1613,7 +1613,7 @@
             pas = [p1]
 
         # deprecated config: merge.followcopies
-        followcopies = repo.ui.configbool('merge', 'followcopies', True)
+        followcopies = repo.ui.configbool('merge', 'followcopies')
         if overwrite:
             followcopies = False
         elif not pas[0]:
--- a/mercurial/obsolete.py	Tue Jul 11 08:52:55 2017 -0700
+++ b/mercurial/obsolete.py	Fri Jul 14 14:22:40 2017 -0700
@@ -991,8 +991,7 @@
     if 'user' not in metadata:
         metadata['user'] = repo.ui.username()
     useoperation = repo.ui.configbool('experimental',
-                                      'evolution.track-operation',
-                                      False)
+        'evolution.track-operation')
     if useoperation and operation:
         metadata['operation'] = operation
     tr = repo.transaction('add-obsolescence-marker')
--- a/mercurial/profiling.py	Tue Jul 11 08:52:55 2017 -0700
+++ b/mercurial/profiling.py	Fri Jul 14 14:22:40 2017 -0700
@@ -30,10 +30,10 @@
 
 @contextlib.contextmanager
 def lsprofile(ui, fp):
-    format = ui.config('profiling', 'format', default='text')
-    field = ui.config('profiling', 'sort', default='inlinetime')
-    limit = ui.configint('profiling', 'limit', default=30)
-    climit = ui.configint('profiling', 'nested', default=0)
+    format = ui.config('profiling', 'format')
+    field = ui.config('profiling', 'sort')
+    limit = ui.configint('profiling', 'limit')
+    climit = ui.configint('profiling', 'nested')
 
     if format not in ['text', 'kcachegrind']:
         ui.warn(_("unrecognized profiling format '%s'"
@@ -72,7 +72,7 @@
             'flamegraph not available - install from '
             'https://github.com/evanhempel/python-flamegraph'))
     # developer config: profiling.freq
-    freq = ui.configint('profiling', 'freq', default=1000)
+    freq = ui.configint('profiling', 'freq')
     filter_ = None
     collapse_recursion = True
     thread = flamegraph.ProfileThread(fp, 1.0 / freq,
@@ -92,7 +92,7 @@
 def statprofile(ui, fp):
     from . import statprof
 
-    freq = ui.configint('profiling', 'freq', default=1000)
+    freq = ui.configint('profiling', 'freq')
     if freq > 0:
         # Cannot reset when profiler is already active. So silently no-op.
         if statprof.state.profile_level == 0:
@@ -107,7 +107,7 @@
     finally:
         data = statprof.stop()
 
-        profformat = ui.config('profiling', 'statformat', 'hotpath')
+        profformat = ui.config('profiling', 'statformat')
 
         formats = {
             'byline': statprof.DisplayFormats.ByLine,
--- a/mercurial/progress.py	Tue Jul 11 08:52:55 2017 -0700
+++ b/mercurial/progress.py	Fri Jul 14 14:22:40 2017 -0700
@@ -92,15 +92,15 @@
         self.startvals = {}
         self.printed = False
         self.lastprint = time.time() + float(self.ui.config(
-            'progress', 'delay', default=3))
+            'progress', 'delay'))
         self.curtopic = None
         self.lasttopic = None
         self.indetcount = 0
         self.refresh = float(self.ui.config(
-            'progress', 'refresh', default=0.1))
+            'progress', 'refresh'))
         self.changedelay = max(3 * self.refresh,
                                float(self.ui.config(
-                                   'progress', 'changedelay', default=1)))
+                                   'progress', 'changedelay')))
         self.order = self.ui.configlist(
             'progress', 'format',
             default=['topic', 'bar', 'number', 'estimate'])
--- a/mercurial/scmutil.py	Tue Jul 11 08:52:55 2017 -0700
+++ b/mercurial/scmutil.py	Fri Jul 14 14:22:40 2017 -0700
@@ -282,7 +282,7 @@
 def checkportabilityalert(ui):
     '''check if the user's config requests nothing, a warning, or abort for
     non-portable filenames'''
-    val = ui.config('ui', 'portablefilenames', 'warn')
+    val = ui.config('ui', 'portablefilenames')
     lval = val.lower()
     bval = util.parsebool(val)
     abort = pycompat.osname == 'nt' or lval == 'abort'
@@ -553,7 +553,7 @@
     Fetch user defined path from config file: [ui] origbackuppath = <path>
     Fall back to default (filepath) if not specified
     '''
-    origbackuppath = ui.config('ui', 'origbackuppath', None)
+    origbackuppath = ui.config('ui', 'origbackuppath')
     if origbackuppath is None:
         return filepath + ".orig"
 
--- a/mercurial/sparse.py	Tue Jul 11 08:52:55 2017 -0700
+++ b/mercurial/sparse.py	Fri Jul 14 14:22:40 2017 -0700
@@ -106,7 +106,7 @@
                     "in rev %s - ignoring it\n" % (profile, ctx))
                 # experimental config: sparse.missingwarning
                 if repo.ui.configbool(
-                        'sparse', 'missingwarning', True):
+                        'sparse', 'missingwarning'):
                     repo.ui.warn(msg)
                 else:
                     repo.ui.debug(msg)
--- a/mercurial/sshpeer.py	Tue Jul 11 08:52:55 2017 -0700
+++ b/mercurial/sshpeer.py	Fri Jul 14 14:22:40 2017 -0700
@@ -146,8 +146,8 @@
         self.port = u.port
         self.path = u.path or "."
 
-        sshcmd = self.ui.config("ui", "ssh", "ssh")
-        remotecmd = self.ui.config("ui", "remotecmd", "hg")
+        sshcmd = self.ui.config("ui", "ssh")
+        remotecmd = self.ui.config("ui", "remotecmd")
 
         args = util.sshargs(sshcmd,
                             _serverquote(self.host),
--- a/mercurial/streamclone.py	Tue Jul 11 08:52:55 2017 -0700
+++ b/mercurial/streamclone.py	Fri Jul 14 14:22:40 2017 -0700
@@ -165,7 +165,7 @@
 
 def allowservergeneration(repo):
     """Whether streaming clones are allowed from the server."""
-    if not repo.ui.configbool('server', 'uncompressed', True, untrusted=True):
+    if not repo.ui.configbool('server', 'uncompressed', untrusted=True):
         return False
 
     # The way stream clone works makes it impossible to hide secret changesets.
--- a/mercurial/subrepo.py	Tue Jul 11 08:52:55 2017 -0700
+++ b/mercurial/subrepo.py	Fri Jul 14 14:22:40 2017 -0700
@@ -401,7 +401,7 @@
     substate = getattr(ctx, "substate", None)
     if not substate:
         return commitphase
-    check = ui.config('phases', 'checksubrepos', 'follow')
+    check = ui.config('phases', 'checksubrepos')
     if check not in ('ignore', 'follow', 'abort'):
         raise error.Abort(_('invalid phases.checksubrepos configuration: %s')
                          % (check))
--- a/mercurial/ui.py	Tue Jul 11 08:52:55 2017 -0700
+++ b/mercurial/ui.py	Fri Jul 14 14:22:40 2017 -0700
@@ -408,8 +408,8 @@
             if self.verbose and self.quiet:
                 self.quiet = self.verbose = False
             self._reportuntrusted = self.debugflag or self.configbool("ui",
-                "report_untrusted", True)
-            self.tracebackflag = self.configbool('ui', 'traceback', False)
+                "report_untrusted")
+            self.tracebackflag = self.configbool('ui', 'traceback')
             self.logblockedtimes = self.configbool('ui', 'logblockedtimes')
 
         if section in (None, 'trusted'):
@@ -924,7 +924,7 @@
                 (util.timer() - starttime) * 1000
 
     def _isatty(self, fh):
-        if self.configbool('ui', 'nontty', False):
+        if self.configbool('ui', 'nontty'):
             return False
         return util.isatty(fh)
 
@@ -947,7 +947,7 @@
         if (self._disablepager
             or self.pageractive
             or command in self.configlist('pager', 'ignore')
-            or not self.configbool('ui', 'paginate', True)
+            or not self.configbool('ui', 'paginate')
             or not self.configbool('pager', 'attend-' + command, True)
             # TODO: if we want to allow HGPLAINEXCEPT=pager,
             # formatted() will need some adjustment.
@@ -1112,7 +1112,7 @@
 
         # Default interface for all the features
         defaultinterface = "text"
-        i = self.config("ui", "interface", None)
+        i = self.config("ui", "interface")
         if i in alldefaults:
             defaultinterface = i
 
@@ -1186,7 +1186,7 @@
         if self.plain():
             return False
 
-        i = self.configbool("ui", "formatted", None)
+        i = self.configbool("ui", "formatted")
         if i is None:
             # some environments replace stdout without implementing isatty
             # usually those are non-interactive
@@ -1464,7 +1464,7 @@
     def _progbar(self):
         """setup the progbar singleton to the ui object"""
         if (self.quiet or self.debugflag
-                or self.configbool('progress', 'disable', False)
+                or self.configbool('progress', 'disable')
                 or not progress.shouldprint(self)):
             return None
         return getprogbar(self)
--- a/mercurial/url.py	Tue Jul 11 08:52:55 2017 -0700
+++ b/mercurial/url.py	Fri Jul 14 14:22:40 2017 -0700
@@ -454,7 +454,7 @@
     authinfo will be added to the password manager
     '''
     # experimental config: ui.usehttp2
-    if ui.configbool('ui', 'usehttp2', False):
+    if ui.configbool('ui', 'usehttp2'):
         handlers = [
             httpconnectionmod.http2handler(
                 ui,
--- a/mercurial/verify.py	Tue Jul 11 08:52:55 2017 -0700
+++ b/mercurial/verify.py	Fri Jul 14 14:22:40 2017 -0700
@@ -443,7 +443,7 @@
                                  (l2, l1), f)
                 except error.CensoredNodeError:
                     # experimental config: censor.policy
-                    if ui.config("censor", "policy", "abort") == "abort":
+                    if ui.config("censor", "policy") == "abort":
                         self.err(lr, _("censored file data"), f)
                 except Exception as inst:
                     self.exc(lr, _("unpacking %s") % short(n), inst, f)
--- a/mercurial/wireproto.py	Tue Jul 11 08:52:55 2017 -0700
+++ b/mercurial/wireproto.py	Fri Jul 14 14:22:40 2017 -0700
@@ -764,7 +764,7 @@
         # otherwise, add 'streamreqs' detailing our local revlog format
         else:
             caps.append('streamreqs=%s' % ','.join(sorted(requiredformats)))
-    if repo.ui.configbool('experimental', 'bundle2-advertise', True):
+    if repo.ui.configbool('experimental', 'bundle2-advertise'):
         capsblob = bundle2.encodecaps(bundle2.getrepocaps(repo))
         caps.append('bundle2=' + urlreq.quote(capsblob))
     caps.append('unbundle=%s' % ','.join(bundle2.bundlepriority))
@@ -772,7 +772,7 @@
     if proto.name == 'http':
         caps.append('httpheader=%d' %
                     repo.ui.configint('server', 'maxhttpheaderlen'))
-        if repo.ui.configbool('experimental', 'httppostargs', False):
+        if repo.ui.configbool('experimental', 'httppostargs'):
             caps.append('httppostargs')
 
         # FUTURE advertise 0.2rx once support is implemented