On Mon, Mar 27, 2017 at 11:38:07AM -0700, Jun Wu wrote: > # HG changeset patch > # User Jun Wu <qu...@fb.com> > # Date 1490639836 25200 > # Mon Mar 27 11:37:16 2017 -0700 > # Node ID 13bee3e959f04f970f2fc0a01120f0b30d725b84 > # Parent 4eb7c76340791f379a34f9df4ec42e0c8b9b2a2f > RFC: switch to immutable configs
I personally like the overall direction > +def _filterconfig(subconfig): > + '''remove configs according to HGPLAIN and HGPLAINEXCEPT > + > + subconfig is an immutable config object. Returns an immutable config > object > + with related fields filtered. > + ''' > + filters = {} > + if _isplain(): > + def filterui(items): > + result = util.sortdict(items) > + for k in ('debug', 'fallbackencoding', 'quiet', 'slash', > + 'logtemplate', 'statuscopies', 'style', > + 'traceback', 'verbose'): > + if k in result: > + del result[k] > + return result > + > + filters['ui'] = filterui > + filters['defaults'] = {} > + if _isplain('alias'): > + filters['alias'] = {} > + if _isplain('revsetalias'): > + filters['revsetalias'] = {} > + if _isplain('templatealias'): > + filters['templatealias'] = {} > + if _isplain('commands'): > + filters['commands'] = {} > + > + if filters: > + return config.filteredconfig('filter', subconfig, filters) > + else: > + return subconfig > + > +def _getconfig(configroot, section, name, default=None, index=0): > + '''get value (index=0) or source (index=-1) from an immutable config''' > + value = configroot.getsection(section).get(name, (None,))[index] > + if value is None: > + value = default > + return value > + > +def _buildconfigroot(cfg, ocfg, gcfg): > + return config.mergedconfig('root', [cfg, ocfg, gcfg]) > + > +def dependson(*fields): > + '''cache result which gets invalidates if any field changes''' > + > + def decorator(oldfunc): > + cached = [[None], None] # cache key, result > + def getcachekey(self): > + return [getattr(self, f, None) for f in fields] > + > + def newfunc(self): > + newkey = getcachekey(self) > + oldkey = cached[0] > + if oldkey == newkey: > + return cached[1] > + result = oldfunc(self) > + cached[:] = [newkey, result] > + return result > + newfunc.__name__ = oldfunc.__name__ > + newfunc.__doc__ = oldfunc.__doc__ > + return newfunc > + return decorator > + > class ui(object): > def __init__(self, src=None): > @@ -146,16 +257,7 @@ class ui(object): > # This exists to prevent an extra list lookup. > self._bufferapplylabels = None > - self.quiet = self.verbose = self.debugflag = self.tracebackflag = > False > - self._reportuntrusted = True > - self._ocfg = config.config() # overlay > - self._tcfg = config.config() # trusted > - self._ucfg = config.config() # untrusted > - self._trustusers = set() > - self._trustgroups = set() > self.callhooks = True > # Insecure server connections requested. > self.insecureconnections = False > - # Blocked time > - self.logblockedtimes = False > # color mode: see mercurial/color.py for possible value > self._colormode = None > @@ -170,9 +272,9 @@ class ui(object): > self._disablepager = src._disablepager > > - self._tcfg = src._tcfg.copy() > - self._ucfg = src._ucfg.copy() > - self._ocfg = src._ocfg.copy() > - self._trustusers = src._trustusers.copy() > - self._trustgroups = src._trustgroups.copy() > + # immutable configs can be reused without copying > + self._ocfgs = src._ocfgs > + self._tcfgs = src._tcfgs > + self._ucfgs = src._ucfgs > + > self.environ = src.environ > self.callhooks = src.callhooks > @@ -182,6 +284,4 @@ class ui(object): > self._styles = src._styles.copy() > > - self.fixconfig() > - > self.httppasswordmgrdb = src.httppasswordmgrdb > self._blockedtimes = src._blockedtimes > @@ -199,4 +299,9 @@ class ui(object): > self._blockedtimes = collections.defaultdict(int) > > + # immutable configs > + self._ocfgs = config.mergedconfig('setconfig', []) # overlay > + self._tcfgs = config.mergedconfig('loaded', []) # trusted i would probably actually call them 'trusted' instead of 'loaded' > + self._ucfgs = config.mergedconfig('loaded', []) # > trusted+untrusted with merge configs in, we would split up trusted+untrusted into trusted and untrusted? > + def setconfig(self, section, name, value, source='', priority=None): I think we can do better by using the title, e.g. 'untrusted', 'setconfig' to access the right layer. a numeric priority seems to be very hard to use and I think we could improve this interface a bit. > + title = source or 'setconfig' > + acfg = config.atomicconfig(title, [(section, name, (value, source))]) > + try: > + cwd = pycompat.getcwd() > + except OSError: > + pass > + else: > + acfg = _fixpathsection(acfg, cwd) > + if priority == 3: > + # global overlay > + self.__class__._gcfgs = self.__class__._gcfgs.append(acfg) > + elif priority == 2: > + # change overlay in this ui > + self._ocfgs = self._ocfgs.append(acfg) > + elif priority == 1: > + # change overlay in this ui, do not override existing overlays > + self._ocfgs = self._ocfgs.prepend(acfg) > + else: > + self._tcfgs = self._tcfgs.append(acfg) > + self._ucfgs = self._ucfgs.append(acfg) > _______________________________________________ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel