Submitter | Boris Feld |
---|---|
Date | Oct. 13, 2017, 5:55 p.m. |
Message ID | <429c6e9c7c3a4f601db1.1507917307@FB> |
Download | mbox | patch |
Permalink | /patch/24840/ |
State | Accepted |
Headers | show |
Comments
On Fri, 13 Oct 2017 19:55:07 +0200, Boris Feld wrote: > # HG changeset patch > # User Boris Feld <boris.feld@octobus.net> > # Date 1507625355 -7200 > # Tue Oct 10 10:49:15 2017 +0200 > # Node ID 429c6e9c7c3a4f601db17c6553a8fcdad35708a8 > # Parent 37b4375b1221e3bda055f0cbecf06b3c9510fd2c > # EXP-Topic config.register.ready > # Available At https://bitbucket.org/octobus/mercurial-devel/ > # hg pull https://bitbucket.org/octobus/mercurial-devel/ -r 429c6e9c7c3a > configitems: allow for the registration of "generic" config item > diff --git a/mercurial/configitems.py b/mercurial/configitems.py > --- a/mercurial/configitems.py > +++ b/mercurial/configitems.py > @@ -8,6 +8,7 @@ > from __future__ import absolute_import > > import functools > +import re > > from . import ( > encoding, > @@ -33,20 +34,56 @@ > :section: the official config section where to find this item, > :name: the official name within the section, > :default: default value for this item, > - :alias: optional list of tuples as alternatives. > + :alias: optional list of tuples as alternatives, > + :generic: this is a generic definition, match name using regular expression. > """ > > - def __init__(self, section, name, default=None, alias=()): > + def __init__(self, section, name, default=None, alias=(), > + generic=False, priority=0): > self.section = section > self.name = name > self.default = default > self.alias = list(alias) > + self.generic = generic > + self.priority = priority > + self._re = None > + if generic: > + self._re = re.compile(self.name) > + > +class itemregister(dict): > + """A specialized dictionary that can handle wild-card selection""" > + > + def __init__(self): > + super(itemregister, self).__init__() > + self._generics = set() > + > + def update(self, other): > + super(itemregister, self).update(other) > + self._generics.update(other._generics) > + > + def __setitem__(self, key, item): > + super(itemregister, self).__setitem__(key, item) Why is a generic item added to the dict too?
On Sat, 14 Oct 2017 14:50:00 +0900, Yuya Nishihara wrote: > On Fri, 13 Oct 2017 19:55:07 +0200, Boris Feld wrote: > > # HG changeset patch > > # User Boris Feld <boris.feld@octobus.net> > > # Date 1507625355 -7200 > > # Tue Oct 10 10:49:15 2017 +0200 > > # Node ID 429c6e9c7c3a4f601db17c6553a8fcdad35708a8 > > # Parent 37b4375b1221e3bda055f0cbecf06b3c9510fd2c > > # EXP-Topic config.register.ready > > # Available At https://bitbucket.org/octobus/mercurial-devel/ > > # hg pull https://bitbucket.org/octobus/mercurial-devel/ -r 429c6e9c7c3a > > configitems: allow for the registration of "generic" config item > > > diff --git a/mercurial/configitems.py b/mercurial/configitems.py > > --- a/mercurial/configitems.py > > +++ b/mercurial/configitems.py > > @@ -8,6 +8,7 @@ > > from __future__ import absolute_import > > > > import functools > > +import re > > > > from . import ( > > encoding, > > @@ -33,20 +34,56 @@ > > :section: the official config section where to find this item, > > :name: the official name within the section, > > :default: default value for this item, > > - :alias: optional list of tuples as alternatives. > > + :alias: optional list of tuples as alternatives, > > + :generic: this is a generic definition, match name using regular expression. > > """ > > > > - def __init__(self, section, name, default=None, alias=()): > > + def __init__(self, section, name, default=None, alias=(), > > + generic=False, priority=0): > > self.section = section > > self.name = name > > self.default = default > > self.alias = list(alias) > > + self.generic = generic > > + self.priority = priority > > + self._re = None > > + if generic: > > + self._re = re.compile(self.name) > > + > > +class itemregister(dict): > > + """A specialized dictionary that can handle wild-card selection""" > > + > > + def __init__(self): > > + super(itemregister, self).__init__() > > + self._generics = set() > > + > > + def update(self, other): > > + super(itemregister, self).update(other) > > + self._generics.update(other._generics) > > + > > + def __setitem__(self, key, item): > > + super(itemregister, self).__setitem__(key, item) > > Why is a generic item added to the dict too? More details: a generic item having pattern r'foo$' matches a literal 'foo$', which seems wrong.
Patch
diff --git a/mercurial/configitems.py b/mercurial/configitems.py --- a/mercurial/configitems.py +++ b/mercurial/configitems.py @@ -8,6 +8,7 @@ from __future__ import absolute_import import functools +import re from . import ( encoding, @@ -33,20 +34,56 @@ :section: the official config section where to find this item, :name: the official name within the section, :default: default value for this item, - :alias: optional list of tuples as alternatives. + :alias: optional list of tuples as alternatives, + :generic: this is a generic definition, match name using regular expression. """ - def __init__(self, section, name, default=None, alias=()): + def __init__(self, section, name, default=None, alias=(), + generic=False, priority=0): self.section = section self.name = name self.default = default self.alias = list(alias) + self.generic = generic + self.priority = priority + self._re = None + if generic: + self._re = re.compile(self.name) + +class itemregister(dict): + """A specialized dictionary that can handle wild-card selection""" + + def __init__(self): + super(itemregister, self).__init__() + self._generics = set() + + def update(self, other): + super(itemregister, self).update(other) + self._generics.update(other._generics) + + def __setitem__(self, key, item): + super(itemregister, self).__setitem__(key, item) + if item.generic: + self._generics.add(item) + + def get(self, key): + if key in self: + return self[key] + + # search for a matching generic item + generics = sorted(self._generics, key=(lambda x: (x.priority, x.name))) + for item in generics: + if item._re.match(key): + return item + + # fallback to dict get + return super(itemregister, self).get(key) coreitems = {} def _register(configtable, *args, **kwargs): item = configitem(*args, **kwargs) - section = configtable.setdefault(item.section, {}) + section = configtable.setdefault(item.section, itemregister()) if item.name in section: msg = "duplicated config item registration for '%s.%s'" raise error.ProgrammingError(msg % (item.section, item.name))