mercurial/configitems.py
changeset 34662 181d913b17e6
parent 34653 8bea493e7297
child 34663 6de7842290b2
equal deleted inserted replaced
34661:eb586ed5d8ce 34662:181d913b17e6
     6 # GNU General Public License version 2 or any later version.
     6 # GNU General Public License version 2 or any later version.
     7 
     7 
     8 from __future__ import absolute_import
     8 from __future__ import absolute_import
     9 
     9 
    10 import functools
    10 import functools
       
    11 import re
    11 
    12 
    12 from . import (
    13 from . import (
    13     encoding,
    14     encoding,
    14     error,
    15     error,
    15 )
    16 )
    31     """represent a known config item
    32     """represent a known config item
    32 
    33 
    33     :section: the official config section where to find this item,
    34     :section: the official config section where to find this item,
    34        :name: the official name within the section,
    35        :name: the official name within the section,
    35     :default: default value for this item,
    36     :default: default value for this item,
    36     :alias: optional list of tuples as alternatives.
    37     :alias: optional list of tuples as alternatives,
       
    38     :generic: this is a generic definition, match name using regular expression.
    37     """
    39     """
    38 
    40 
    39     def __init__(self, section, name, default=None, alias=()):
    41     def __init__(self, section, name, default=None, alias=(),
       
    42                  generic=False, priority=0):
    40         self.section = section
    43         self.section = section
    41         self.name = name
    44         self.name = name
    42         self.default = default
    45         self.default = default
    43         self.alias = list(alias)
    46         self.alias = list(alias)
       
    47         self.generic = generic
       
    48         self.priority = priority
       
    49         self._re = None
       
    50         if generic:
       
    51             self._re = re.compile(self.name)
       
    52 
       
    53 class itemregister(dict):
       
    54     """A specialized dictionary that can handle wild-card selection"""
       
    55 
       
    56     def __init__(self):
       
    57         super(itemregister, self).__init__()
       
    58         self._generics = set()
       
    59 
       
    60     def update(self, other):
       
    61         super(itemregister, self).update(other)
       
    62         self._generics.update(other._generics)
       
    63 
       
    64     def __setitem__(self, key, item):
       
    65         super(itemregister, self).__setitem__(key, item)
       
    66         if item.generic:
       
    67             self._generics.add(item)
       
    68 
       
    69     def get(self, key):
       
    70         if key in self:
       
    71             return self[key]
       
    72 
       
    73         # search for a matching generic item
       
    74         generics = sorted(self._generics, key=(lambda x: (x.priority, x.name)))
       
    75         for item in generics:
       
    76             if item._re.match(key):
       
    77                 return item
       
    78 
       
    79         # fallback to dict get
       
    80         return super(itemregister, self).get(key)
    44 
    81 
    45 coreitems = {}
    82 coreitems = {}
    46 
    83 
    47 def _register(configtable, *args, **kwargs):
    84 def _register(configtable, *args, **kwargs):
    48     item = configitem(*args, **kwargs)
    85     item = configitem(*args, **kwargs)
    49     section = configtable.setdefault(item.section, {})
    86     section = configtable.setdefault(item.section, itemregister())
    50     if item.name in section:
    87     if item.name in section:
    51         msg = "duplicated config item registration for '%s.%s'"
    88         msg = "duplicated config item registration for '%s.%s'"
    52         raise error.ProgrammingError(msg % (item.section, item.name))
    89         raise error.ProgrammingError(msg % (item.section, item.name))
    53     section[item.name] = item
    90     section[item.name] = item
    54 
    91