mercurial/config.py
changeset 46660 d3df397e7a59
parent 46659 7621ab4005bf
child 46661 a3dced4b7b04
equal deleted inserted replaced
46659:7621ab4005bf 46660:d3df397e7a59
    25         self._data = {}
    25         self._data = {}
    26         self._unset = []
    26         self._unset = []
    27         if data:
    27         if data:
    28             for k in data._data:
    28             for k in data._data:
    29                 self._data[k] = data[k].copy()
    29                 self._data[k] = data[k].copy()
    30             self._source = data._source.copy()
       
    31         else:
       
    32             self._source = util.cowdict()
       
    33 
    30 
    34     def copy(self):
    31     def copy(self):
    35         return config(self)
    32         return config(self)
    36 
    33 
    37     def __contains__(self, section):
    34     def __contains__(self, section):
    46     def __iter__(self):
    43     def __iter__(self):
    47         for d in self.sections():
    44         for d in self.sections():
    48             yield d
    45             yield d
    49 
    46 
    50     def update(self, src):
    47     def update(self, src):
    51         self._source = self._source.preparewrite()
       
    52         for s, n in src._unset:
    48         for s, n in src._unset:
    53             ds = self._data.get(s, None)
    49             ds = self._data.get(s, None)
    54             if ds is not None and n in ds:
    50             if ds is not None and n in ds:
    55                 self._data[s] = ds.preparewrite()
    51                 self._data[s] = ds.preparewrite()
    56                 del self._data[s][n]
    52                 del self._data[s][n]
    57                 del self._source[(s, n)]
       
    58         for s in src:
    53         for s in src:
    59             ds = self._data.get(s, None)
    54             ds = self._data.get(s, None)
    60             if ds:
    55             if ds:
    61                 self._data[s] = ds.preparewrite()
    56                 self._data[s] = ds.preparewrite()
    62             else:
    57             else:
    63                 self._data[s] = util.cowsortdict()
    58                 self._data[s] = util.cowsortdict()
    64             self._data[s].update(src._data[s])
    59             self._data[s].update(src._data[s])
    65         self._source.update(src._source)
    60 
       
    61     def _get(self, section, item):
       
    62         return self._data.get(section, {}).get(item)
    66 
    63 
    67     def get(self, section, item, default=None):
    64     def get(self, section, item, default=None):
    68         return self._data.get(section, {}).get(item, default)
    65         result = self._get(section, item)
    69 
    66         if result is None:
    70     def backup(self, section, item):
    67             return default
       
    68         return result[0]
       
    69 
       
    70     def backup(self, section, key):
    71         """return a tuple allowing restore to reinstall a previous value
    71         """return a tuple allowing restore to reinstall a previous value
    72 
    72 
    73         The main reason we need it is because it handles the "no data" case.
    73         The main reason we need it is because it handles the "no data" case.
    74         """
    74         """
    75         try:
    75         try:
    76             value = self._data[section][item]
    76             item = self._data[section][key]
    77             source = self.source(section, item)
       
    78             return (section, item, value, source)
       
    79         except KeyError:
    77         except KeyError:
    80             return (section, item)
    78             return (section, key)
       
    79         else:
       
    80             return (section, key) + item
    81 
    81 
    82     def source(self, section, item):
    82     def source(self, section, item):
    83         return self._source.get((section, item), b"")
    83         result = self._get(section, item)
       
    84         if result is None:
       
    85             return b""
       
    86         return result[1]
    84 
    87 
    85     def sections(self):
    88     def sections(self):
    86         return sorted(self._data.keys())
    89         return sorted(self._data.keys())
    87 
    90 
    88     def items(self, section):
    91     def items(self, section):
    89         return list(pycompat.iteritems(self._data.get(section, {})))
    92         items = pycompat.iteritems(self._data.get(section, {}))
       
    93         return [(k, v) for (k, (v, s)) in items]
    90 
    94 
    91     def set(self, section, item, value, source=b""):
    95     def set(self, section, item, value, source=b""):
    92         if pycompat.ispy3:
    96         if pycompat.ispy3:
    93             assert not isinstance(
    97             assert not isinstance(
    94                 section, str
    98                 section, str
   101             ), b'config values may not be unicode strings on Python 3'
   105             ), b'config values may not be unicode strings on Python 3'
   102         if section not in self:
   106         if section not in self:
   103             self._data[section] = util.cowsortdict()
   107             self._data[section] = util.cowsortdict()
   104         else:
   108         else:
   105             self._data[section] = self._data[section].preparewrite()
   109             self._data[section] = self._data[section].preparewrite()
   106         self._data[section][item] = value
   110         self._data[section][item] = (value, source)
   107         if source:
       
   108             self._source = self._source.preparewrite()
       
   109             self._source[(section, item)] = source
       
   110 
   111 
   111     def alter(self, section, key, new_value):
   112     def alter(self, section, key, new_value):
   112         """alter a value without altering its source or level
   113         """alter a value without altering its source or level
   113 
   114 
   114         This method is meant to be used by `ui.fixconfig` only."""
   115         This method is meant to be used by `ui.fixconfig` only."""
   118         assert len(new_item) == size
   119         assert len(new_item) == size
   119         self._data[section][key] = new_item
   120         self._data[section][key] = new_item
   120 
   121 
   121     def restore(self, data):
   122     def restore(self, data):
   122         """restore data returned by self.backup"""
   123         """restore data returned by self.backup"""
   123         self._source = self._source.preparewrite()
   124         if len(data) != 2:
   124         if len(data) == 4:
       
   125             # restore old data
   125             # restore old data
   126             section, item, value, source = data
   126             section, key = data[:2]
       
   127             item = data[2:]
   127             self._data[section] = self._data[section].preparewrite()
   128             self._data[section] = self._data[section].preparewrite()
   128             self._data[section][item] = value
   129             self._data[section][key] = item
   129             self._source[(section, item)] = source
       
   130         else:
   130         else:
   131             # no data before, remove everything
   131             # no data before, remove everything
   132             section, item = data
   132             section, item = data
   133             if section in self._data:
   133             if section in self._data:
   134                 self._data[section].pop(item, None)
   134                 self._data[section].pop(item, None)
   135             self._source.pop((section, item), None)
       
   136 
   135 
   137     def parse(self, src, data, sections=None, remap=None, include=None):
   136     def parse(self, src, data, sections=None, remap=None, include=None):
   138         sectionre = util.re.compile(br'\[([^\[]+)\]')
   137         sectionre = util.re.compile(br'\[([^\[]+)\]')
   139         itemre = util.re.compile(br'([^=\s][^=]*?)\s*=\s*(.*\S|)')
   138         itemre = util.re.compile(br'([^=\s][^=]*?)\s*=\s*(.*\S|)')
   140         contre = util.re.compile(br'\s+(\S|\S.*\S)\s*$')
   139         contre = util.re.compile(br'\s+(\S|\S.*\S)\s*$')