[PATCH 1 of 2] ui: factor out ui.load() to create a ui without loading configs (API)

Yuya Nishihara yuya at tcha.org
Sun Nov 27 08:45:15 EST 2016


# HG changeset patch
# User Yuya Nishihara <yuya at tcha.org>
# Date 1477114510 -32400
#      Sat Oct 22 14:35:10 2016 +0900
# Node ID a8627780e15c1382e11f1d5df0f33843497dbac7
# Parent  6c1f9bd1e65db3e44431f7623d6adc5a8c5d9c36
ui: factor out ui.load() to create a ui without loading configs (API)

This allows us to write doctests depending on a ui object, but not on global
configs.

ui.load() is a class method so we can do wsgiui.load(). All ui() calls but
for doctests are replaced with ui.load(). Some of them could be changed to
not load configs later.

diff --git a/contrib/benchmarks/__init__.py b/contrib/benchmarks/__init__.py
--- a/contrib/benchmarks/__init__.py
+++ b/contrib/benchmarks/__init__.py
@@ -50,7 +50,7 @@ outputre = re.compile((r'! wall (\d+.\d+
 
 def runperfcommand(reponame, command, *args, **kwargs):
     os.environ["HGRCPATH"] = os.environ.get("ASVHGRCPATH", "")
-    ui = uimod.ui()
+    ui = uimod.ui.load()
     repo = hg.repository(ui, os.path.join(reposdir, reponame))
     perfext = extensions.load(ui, 'perfext',
                               os.path.join(basedir, 'contrib', 'perf.py'))
diff --git a/contrib/simplemerge b/contrib/simplemerge
--- a/contrib/simplemerge
+++ b/contrib/simplemerge
@@ -54,7 +54,7 @@ try:
         sys.exit(0)
     if len(args) != 3:
             raise ParseError(_('wrong number of arguments'))
-    sys.exit(simplemerge.simplemerge(ui.ui(), *args, **opts))
+    sys.exit(simplemerge.simplemerge(ui.ui.load(), *args, **opts))
 except ParseError as e:
     sys.stdout.write("%s: %s\n" % (sys.argv[0], e))
     showhelp()
diff --git a/doc/check-seclevel.py b/doc/check-seclevel.py
--- a/doc/check-seclevel.py
+++ b/doc/check-seclevel.py
@@ -158,7 +158,7 @@ option.
 
     (options, args) = optparser.parse_args()
 
-    ui = uimod.ui()
+    ui = uimod.ui.load()
     ui.setconfig('ui', 'verbose', options.verbose, '--verbose')
     ui.setconfig('ui', 'debug', options.debug, '--debug')
 
diff --git a/doc/gendoc.py b/doc/gendoc.py
--- a/doc/gendoc.py
+++ b/doc/gendoc.py
@@ -217,7 +217,7 @@ if __name__ == "__main__":
     if len(sys.argv) > 1:
         doc = sys.argv[1]
 
-    ui = uimod.ui()
+    ui = uimod.ui.load()
     if doc == 'hg.1.gendoc':
         showdoc(ui)
     else:
diff --git a/mercurial/dispatch.py b/mercurial/dispatch.py
--- a/mercurial/dispatch.py
+++ b/mercurial/dispatch.py
@@ -101,7 +101,7 @@ def dispatch(req):
 
     try:
         if not req.ui:
-            req.ui = uimod.ui()
+            req.ui = uimod.ui.load()
         if '--traceback' in req.args:
             req.ui.setconfig('ui', 'traceback', 'on', '--traceback')
 
diff --git a/mercurial/hgweb/hgweb_mod.py b/mercurial/hgweb/hgweb_mod.py
--- a/mercurial/hgweb/hgweb_mod.py
+++ b/mercurial/hgweb/hgweb_mod.py
@@ -224,7 +224,7 @@ class hgweb(object):
             if baseui:
                 u = baseui.copy()
             else:
-                u = uimod.ui()
+                u = uimod.ui.load()
             r = hg.repository(u, repo)
         else:
             # we trust caller to give us a private copy
@@ -467,4 +467,3 @@ def getwebview(repo):
         return repo.filtered(viewconfig)
     else:
         return repo.filtered('served')
-
diff --git a/mercurial/hgweb/hgwebdir_mod.py b/mercurial/hgweb/hgwebdir_mod.py
--- a/mercurial/hgweb/hgwebdir_mod.py
+++ b/mercurial/hgweb/hgwebdir_mod.py
@@ -136,7 +136,7 @@ class hgwebdir(object):
         if self.baseui:
             u = self.baseui.copy()
         else:
-            u = uimod.ui()
+            u = uimod.ui.load()
             u.setconfig('ui', 'report_untrusted', 'off', 'hgwebdir')
             u.setconfig('ui', 'nontty', 'true', 'hgwebdir')
             # displaying bundling progress bar while serving feels wrong and may
diff --git a/mercurial/hgweb/webcommands.py b/mercurial/hgweb/webcommands.py
--- a/mercurial/hgweb/webcommands.py
+++ b/mercurial/hgweb/webcommands.py
@@ -1302,7 +1302,7 @@ def help(web, req, tmpl):
         return tmpl('helptopics', topics=topics, title=topicname,
                     subindex=True)
 
-    u = webutil.wsgiui()
+    u = webutil.wsgiui.load()
     u.verbose = True
 
     # Render a page from a sub-topic.
diff --git a/mercurial/ui.py b/mercurial/ui.py
--- a/mercurial/ui.py
+++ b/mercurial/ui.py
@@ -96,6 +96,12 @@ default = %s
 
 class ui(object):
     def __init__(self, src=None):
+        """Create a fresh new ui object if no src given
+
+        Use uimod.ui.load() to create a ui which knows global and user configs.
+        In most cases, you should use ui.copy() to create a copy of an existing
+        ui object.
+        """
         # _buffers: used for temporary capture of output
         self._buffers = []
         # 3-tuple describing how each buffer in the stack behaves.
@@ -138,12 +144,18 @@ class ui(object):
 
             # shared read-only environment
             self.environ = os.environ
-            # we always trust global config files
-            for f in scmutil.rcpath():
-                self.readconfig(f, trust=True)
 
             self.httppasswordmgrdb = urlreq.httppasswordmgrwithdefaultrealm()
 
+    @classmethod
+    def load(cls):
+        """Create a ui and load global and user configs"""
+        u = cls()
+        # we always trust global config files
+        for f in scmutil.rcpath():
+            u.readconfig(f, trust=True)
+        return u
+
     def copy(self):
         return self.__class__(self)
 
diff --git a/tests/dummysmtpd.py b/tests/dummysmtpd.py
--- a/tests/dummysmtpd.py
+++ b/tests/dummysmtpd.py
@@ -37,7 +37,7 @@ class dummysmtpsecureserver(dummysmtpser
         if not pair:
             return
         conn, addr = pair
-        ui = uimod.ui()
+        ui = uimod.ui.load()
         try:
             # wrap_socket() would block, but we don't care
             conn = sslutil.wrapserversocket(conn, ui, certfile=self._certfile)
diff --git a/tests/hghave.py b/tests/hghave.py
--- a/tests/hghave.py
+++ b/tests/hghave.py
@@ -449,7 +449,7 @@ def has_sslcontext():
 @check("defaultcacerts", "can verify SSL certs by system's CA certs store")
 def has_defaultcacerts():
     from mercurial import sslutil, ui as uimod
-    ui = uimod.ui()
+    ui = uimod.ui.load()
     return sslutil._defaultcacerts(ui) or sslutil._canloaddefaultcerts
 
 @check("defaultcacertsloaded", "detected presence of loaded system CA certs")
@@ -462,7 +462,7 @@ def has_defaultcacertsloaded():
     if not has_sslcontext():
         return False
 
-    ui = uimod.ui()
+    ui = uimod.ui.load()
     cafile = sslutil._defaultcacerts(ui)
     ctx = ssl.create_default_context()
     if cafile:
diff --git a/tests/test-ancestor.py b/tests/test-ancestor.py
--- a/tests/test-ancestor.py
+++ b/tests/test-ancestor.py
@@ -218,7 +218,7 @@ dagtests = [
     '+3*3/*2*2/*4*4/*4/2*4/2*2',
 ]
 def test_gca():
-    u = uimod.ui()
+    u = uimod.ui.load()
     for i, dag in enumerate(dagtests):
         repo = hg.repository(u, 'gca%d' % i, create=1)
         cl = repo.changelog
diff --git a/tests/test-basic.t b/tests/test-basic.t
--- a/tests/test-basic.t
+++ b/tests/test-basic.t
@@ -34,7 +34,7 @@ Verify that updating to revision 0 via c
 
   $ cat <<EOF > update_to_rev0.py
   > from mercurial import ui, hg, commands
-  > myui = ui.ui()
+  > myui = ui.ui.load()
   > repo = hg.repository(myui, path='.')
   > commands.update(myui, repo, rev=0)
   > EOF
diff --git a/tests/test-bisect.t b/tests/test-bisect.t
--- a/tests/test-bisect.t
+++ b/tests/test-bisect.t
@@ -456,7 +456,7 @@ test bisecting command
   > #!/usr/bin/env python
   > import sys
   > from mercurial import ui, hg
-  > repo = hg.repository(ui.ui(), '.')
+  > repo = hg.repository(ui.ui.load(), '.')
   > if repo['.'].rev() < 6:
   >     sys.exit(1)
   > EOF
diff --git a/tests/test-clone.t b/tests/test-clone.t
--- a/tests/test-clone.t
+++ b/tests/test-clone.t
@@ -513,7 +513,7 @@ iterable in addbranchrevs()
 
   $ cat <<EOF > simpleclone.py
   > from mercurial import ui, hg
-  > myui = ui.ui()
+  > myui = ui.ui.load()
   > repo = hg.repository(myui, 'a')
   > hg.clone(myui, {}, repo, dest="ua")
   > EOF
@@ -526,7 +526,7 @@ iterable in addbranchrevs()
 
   $ cat <<EOF > branchclone.py
   > from mercurial import ui, hg, extensions
-  > myui = ui.ui()
+  > myui = ui.ui.load()
   > extensions.loadall(myui)
   > repo = hg.repository(myui, 'a')
   > hg.clone(myui, {}, repo, dest="ua", branch=["stable",])
diff --git a/tests/test-commit-interactive-curses.t b/tests/test-commit-interactive-curses.t
--- a/tests/test-commit-interactive-curses.t
+++ b/tests/test-commit-interactive-curses.t
@@ -325,7 +325,7 @@ The default interface is text
   $ chunkselectorinterface() {
   > python <<EOF
   > from mercurial import hg, ui, parsers;\
-  > repo = hg.repository(ui.ui(), ".");\
+  > repo = hg.repository(ui.ui.load(), ".");\
   > print repo.ui.interface("chunkselector")
   > EOF
   > }
diff --git a/tests/test-commit-multiple.t b/tests/test-commit-multiple.t
--- a/tests/test-commit-multiple.t
+++ b/tests/test-commit-multiple.t
@@ -92,7 +92,7 @@ now test that we fixed the bug for all s
   > def printfiles(repo, rev):
   >     print "revision %s files: %s" % (rev, repo[rev].files())
   > 
-  > repo = hg.repository(ui.ui(), '.')
+  > repo = hg.repository(ui.ui.load(), '.')
   > assert len(repo) == 6, \
   >        "initial: len(repo): %d, expected: 6" % len(repo)
   > 
diff --git a/tests/test-commit.t b/tests/test-commit.t
--- a/tests/test-commit.t
+++ b/tests/test-commit.t
@@ -609,7 +609,7 @@ verify pathauditor blocks evil filepaths
   $ cat > evil-commit.py <<EOF
   > from mercurial import ui, hg, context, node
   > notrc = u".h\u200cg".encode('utf-8') + '/hgrc'
-  > u = ui.ui()
+  > u = ui.ui.load()
   > r = hg.repository(u, '.')
   > def filectxfn(repo, memctx, path):
   >     return context.memfilectx(repo, path, '[hooks]\nupdate = echo owned')
@@ -633,7 +633,7 @@ verify pathauditor blocks evil filepaths
   $ cat > evil-commit.py <<EOF
   > from mercurial import ui, hg, context, node
   > notrc = "HG~1/hgrc"
-  > u = ui.ui()
+  > u = ui.ui.load()
   > r = hg.repository(u, '.')
   > def filectxfn(repo, memctx, path):
   >     return context.memfilectx(repo, path, '[hooks]\nupdate = echo owned')
@@ -651,7 +651,7 @@ verify pathauditor blocks evil filepaths
   $ cat > evil-commit.py <<EOF
   > from mercurial import ui, hg, context, node
   > notrc = "HG8B6C~2/hgrc"
-  > u = ui.ui()
+  > u = ui.ui.load()
   > r = hg.repository(u, '.')
   > def filectxfn(repo, memctx, path):
   >     return context.memfilectx(repo, path, '[hooks]\nupdate = echo owned')
diff --git a/tests/test-context.py b/tests/test-context.py
--- a/tests/test-context.py
+++ b/tests/test-context.py
@@ -7,7 +7,7 @@ from mercurial import (
     ui as uimod,
 )
 
-u = uimod.ui()
+u = uimod.ui.load()
 
 repo = hg.repository(u, 'test1', create=1)
 os.chdir('test1')
diff --git a/tests/test-duplicateoptions.py b/tests/test-duplicateoptions.py
--- a/tests/test-duplicateoptions.py
+++ b/tests/test-duplicateoptions.py
@@ -21,7 +21,7 @@ for ext in disabled:
 
 hgrc.close()
 
-u = uimod.ui()
+u = uimod.ui.load()
 extensions.loadall(u)
 
 globalshort = set()
diff --git a/tests/test-filecache.py b/tests/test-filecache.py
--- a/tests/test-filecache.py
+++ b/tests/test-filecache.py
@@ -141,7 +141,7 @@ def fakeuncacheable():
 def test_filecache_synced():
     # test old behavior that caused filecached properties to go out of sync
     os.system('hg init && echo a >> a && hg ci -qAm.')
-    repo = hg.repository(uimod.ui())
+    repo = hg.repository(uimod.ui.load())
     # first rollback clears the filecache, but changelog to stays in __dict__
     repo.rollback()
     repo.commit('.')
diff --git a/tests/test-filelog.py b/tests/test-filelog.py
--- a/tests/test-filelog.py
+++ b/tests/test-filelog.py
@@ -13,7 +13,7 @@ from mercurial import (
     ui as uimod,
 )
 
-myui = uimod.ui()
+myui = uimod.ui.load()
 repo = hg.repository(myui, path='.', create=True)
 
 fl = repo.file('foobar')
diff --git a/tests/test-hgweb-auth.py b/tests/test-hgweb-auth.py
--- a/tests/test-hgweb-auth.py
+++ b/tests/test-hgweb-auth.py
@@ -15,7 +15,7 @@ class myui(uimod.ui):
     def interactive(self):
         return False
 
-origui = myui()
+origui = myui.load()
 
 def writeauth(items):
     ui = origui.copy()
diff --git a/tests/test-hgwebdir-paths.py b/tests/test-hgwebdir-paths.py
--- a/tests/test-hgwebdir-paths.py
+++ b/tests/test-hgwebdir-paths.py
@@ -15,7 +15,7 @@ os.chdir('webdir')
 
 webdir = os.path.realpath('.')
 
-u = uimod.ui()
+u = uimod.ui.load()
 hg.repository(u, 'a', create=1)
 hg.repository(u, 'b', create=1)
 os.chdir('b')
diff --git a/tests/test-http-branchmap.t b/tests/test-http-branchmap.t
--- a/tests/test-http-branchmap.t
+++ b/tests/test-http-branchmap.t
@@ -81,7 +81,7 @@ verify 7e7d56fe4833 (encoding fallback i
   > sys.stdout = StdoutWrapper(sys.stdout)
   > sys.stderr = StdoutWrapper(sys.stderr)
   > 
-  > myui = ui.ui()
+  > myui = ui.ui.load()
   > repo = hg.repository(myui, 'a')
   > commands.serve(myui, repo, stdio=True, cmdserver=False)
   > EOF
diff --git a/tests/test-propertycache.py b/tests/test-propertycache.py
--- a/tests/test-propertycache.py
+++ b/tests/test-propertycache.py
@@ -46,7 +46,7 @@ localrepo.localrepository.testcachedunfi
 # these tests on the real object to detect regression.
 repopath = os.path.join(os.environ['TESTTMP'], 'repo')
 assert subprocess.call(['hg', 'init', repopath]) == 0
-ui = uimod.ui()
+ui = uimod.ui.load()
 repo = hg.repository(ui, path=repopath).unfiltered()
 
 
diff --git a/tests/test-revlog-ancestry.py b/tests/test-revlog-ancestry.py
--- a/tests/test-revlog-ancestry.py
+++ b/tests/test-revlog-ancestry.py
@@ -6,7 +6,7 @@ from mercurial import (
     ui as uimod,
 )
 
-u = uimod.ui()
+u = uimod.ui.load()
 
 repo = hg.repository(u, 'test1', create=1)
 os.chdir('test1')
diff --git a/tests/test-status-inprocess.py b/tests/test-status-inprocess.py
--- a/tests/test-status-inprocess.py
+++ b/tests/test-status-inprocess.py
@@ -7,7 +7,7 @@ from mercurial import (
     ui as uimod,
 )
 
-u = uimod.ui()
+u = uimod.ui.load()
 
 print('% creating repo')
 repo = localrepo.localrepository(u, '.', create=True)
diff --git a/tests/test-symlink-os-yes-fs-no.py b/tests/test-symlink-os-yes-fs-no.py
--- a/tests/test-symlink-os-yes-fs-no.py
+++ b/tests/test-symlink-os-yes-fs-no.py
@@ -17,7 +17,7 @@ BUNDLEPATH = os.path.join(TESTDIR, 'bund
 if not getattr(os, "symlink", False):
     sys.exit(80) # SKIPPED_STATUS defined in run-tests.py
 
-u = uimod.ui()
+u = uimod.ui.load()
 # hide outer repo
 hg.peer(u, {}, '.', create=True)
 
@@ -48,10 +48,10 @@ for f in 'test0/a.lnk', 'test0/d/b.lnk':
     fp.close()
 
 # reload repository
-u = uimod.ui()
+u = uimod.ui.load()
 repo = hg.repository(u, 'test0')
 commands.status(u, repo)
 
 # try cloning a repo which contains symlinks
-u = uimod.ui()
+u = uimod.ui.load()
 hg.clone(u, {}, BUNDLEPATH, 'test1')
diff --git a/tests/test-trusted.py b/tests/test-trusted.py
--- a/tests/test-trusted.py
+++ b/tests/test-trusted.py
@@ -66,7 +66,7 @@ def testui(user='foo', group='bar', tuse
     print('# %s user, %s group%s' % (kind[user == cuser], kind[group == cgroup],
                                      trusted))
 
-    u = uimod.ui()
+    u = uimod.ui.load()
     u.setconfig('ui', 'debug', str(bool(debug)))
     u.setconfig('ui', 'report_untrusted', str(bool(report)))
     u.readconfig('.hg/hgrc')
@@ -156,7 +156,7 @@ print(u.config('foobar', 'baz'))
 
 print()
 print("# read trusted, untrusted, new ui, trusted")
-u = uimod.ui()
+u = uimod.ui.load()
 u.setconfig('ui', 'debug', 'on')
 u.readconfig(filename)
 u2 = u.copy()
diff --git a/tests/test-ui-color.py b/tests/test-ui-color.py
--- a/tests/test-ui-color.py
+++ b/tests/test-ui-color.py
@@ -23,7 +23,7 @@ hgrc.write('[extensions]\n')
 hgrc.write('color=\n')
 hgrc.close()
 
-ui_ = uimod.ui()
+ui_ = uimod.ui.load()
 ui_.setconfig('ui', 'formatted', 'True')
 
 # we're not interested in the output, so write that to devnull
diff --git a/tests/test-ui-config.py b/tests/test-ui-config.py
--- a/tests/test-ui-config.py
+++ b/tests/test-ui-config.py
@@ -5,7 +5,7 @@ from mercurial import (
     ui as uimod,
 )
 
-testui = uimod.ui()
+testui = uimod.ui.load()
 parsed = dispatch._parseconfig(testui, [
     'values.string=string value',
     'values.bool1=true',
diff --git a/tests/test-ui-verbosity.py b/tests/test-ui-verbosity.py
--- a/tests/test-ui-verbosity.py
+++ b/tests/test-ui-verbosity.py
@@ -32,7 +32,7 @@ for i in xrange(64):
         f.write('debug = True\n')
     f.close()
 
-    u = uimod.ui()
+    u = uimod.ui.load()
     if cmd_quiet or cmd_debug or cmd_verbose:
         u.setconfig('ui', 'quiet', str(bool(cmd_quiet)))
         u.setconfig('ui', 'verbose', str(bool(cmd_verbose)))
diff --git a/tests/test-walkrepo.py b/tests/test-walkrepo.py
--- a/tests/test-walkrepo.py
+++ b/tests/test-walkrepo.py
@@ -16,7 +16,7 @@ pjoin = os.path.join
 walkrepos = scmutil.walkrepos
 checklink = util.checklink
 
-u = uimod.ui()
+u = uimod.ui.load()
 sym = checklink('.')
 
 hg.repository(u, 'top1', create=1)


More information about the Mercurial-devel mailing list