Mercurial > hg
annotate mercurial/config.py @ 52032:09a54892b7ee
mergestate: reduce the number of attribute lookups
This code is called a lot during updates, this is a very small but also very
easy thing to do.
author | Raphaël Gomès <rgomes@octobus.net> |
---|---|
date | Wed, 21 Aug 2024 09:48:14 +0200 |
parents | f4733654f144 |
children |
rev | line source |
---|---|
8229
ddf3d6656e7c
config: add copyright and license header
Martin Geisler <mg@lazybytes.net>
parents:
8222
diff
changeset
|
1 # config.py - configuration parsing for Mercurial |
ddf3d6656e7c
config: add copyright and license header
Martin Geisler <mg@lazybytes.net>
parents:
8222
diff
changeset
|
2 # |
46819
d4ba4d51f85f
contributor: change mentions of mpm to olivia
Raphaël Gomès <rgomes@octobus.net>
parents:
46622
diff
changeset
|
3 # Copyright 2009 Olivia Mackall <olivia@selenic.com> and others |
8229
ddf3d6656e7c
config: add copyright and license header
Martin Geisler <mg@lazybytes.net>
parents:
8222
diff
changeset
|
4 # |
ddf3d6656e7c
config: add copyright and license header
Martin Geisler <mg@lazybytes.net>
parents:
8222
diff
changeset
|
5 # This software may be used and distributed according to the terms of the |
10263 | 6 # GNU General Public License version 2 or any later version. |
8229
ddf3d6656e7c
config: add copyright and license header
Martin Geisler <mg@lazybytes.net>
parents:
8222
diff
changeset
|
7 |
51863
f4733654f144
typing: add `from __future__ import annotations` to most files
Matt Harbison <matt_harbison@yahoo.com>
parents:
51289
diff
changeset
|
8 from __future__ import annotations |
25923
a027a0813b44
config: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
9 |
a027a0813b44
config: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
10 import errno |
a027a0813b44
config: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
11 import os |
a027a0813b44
config: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
12 |
51289
7bd7fcc711f2
pytype: drop the last inline type comment
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50929
diff
changeset
|
13 from typing import ( |
7bd7fcc711f2
pytype: drop the last inline type comment
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50929
diff
changeset
|
14 List, |
7bd7fcc711f2
pytype: drop the last inline type comment
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50929
diff
changeset
|
15 Tuple, |
7bd7fcc711f2
pytype: drop the last inline type comment
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50929
diff
changeset
|
16 ) |
7bd7fcc711f2
pytype: drop the last inline type comment
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50929
diff
changeset
|
17 |
25923
a027a0813b44
config: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
18 from .i18n import _ |
a027a0813b44
config: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
19 from . import ( |
43276
d201a637c971
py3: encode underlying error message during parse error of %include
Denis Laxalde <denis.laxalde@logilab.fr>
parents:
43106
diff
changeset
|
20 encoding, |
25923
a027a0813b44
config: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
21 error, |
a027a0813b44
config: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
22 util, |
a027a0813b44
config: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
23 ) |
8144 | 24 |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41317
diff
changeset
|
25 |
48946
642e31cb55f0
py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents:
48920
diff
changeset
|
26 class config: |
45254
3f54242781e9
config: remove now-unused support for "includepaths"
Martin von Zweigbergk <martinvonz@google.com>
parents:
45208
diff
changeset
|
27 def __init__(self, data=None): |
46622
a3dced4b7b04
config: track the "level" of a value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46621
diff
changeset
|
28 self._current_source_level = 0 |
8144 | 29 self._data = {} |
19087
7d82ad4b3727
config: discard "%unset" values defined in the other files read in previously
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
17537
diff
changeset
|
30 self._unset = [] |
8144 | 31 if data: |
32 for k in data._data: | |
33 self._data[k] = data[k].copy() | |
46622
a3dced4b7b04
config: track the "level" of a value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46621
diff
changeset
|
34 self._current_source_level = data._current_source_level + 1 |
a3dced4b7b04
config: track the "level" of a value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46621
diff
changeset
|
35 |
a3dced4b7b04
config: track the "level" of a value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46621
diff
changeset
|
36 def new_source(self): |
a3dced4b7b04
config: track the "level" of a value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46621
diff
changeset
|
37 """increment the source counter |
a3dced4b7b04
config: track the "level" of a value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46621
diff
changeset
|
38 |
a3dced4b7b04
config: track the "level" of a value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46621
diff
changeset
|
39 This is used to define source priority when reading""" |
a3dced4b7b04
config: track the "level" of a value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46621
diff
changeset
|
40 self._current_source_level += 1 |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41317
diff
changeset
|
41 |
8144 | 42 def copy(self): |
43 return config(self) | |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41317
diff
changeset
|
44 |
8144 | 45 def __contains__(self, section): |
46 return section in self._data | |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41317
diff
changeset
|
47 |
27696
e70c97cc9243
config: add hasconfig method and supporting plumbing
Bryan O'Sullivan <bos@serpentine.com>
parents:
25923
diff
changeset
|
48 def hasitem(self, section, item): |
e70c97cc9243
config: add hasconfig method and supporting plumbing
Bryan O'Sullivan <bos@serpentine.com>
parents:
25923
diff
changeset
|
49 return item in self._data.get(section, {}) |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41317
diff
changeset
|
50 |
8186
6a0018cdb2fe
config: add some helper methods
Matt Mackall <mpm@selenic.com>
parents:
8185
diff
changeset
|
51 def __getitem__(self, section): |
6a0018cdb2fe
config: add some helper methods
Matt Mackall <mpm@selenic.com>
parents:
8185
diff
changeset
|
52 return self._data.get(section, {}) |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41317
diff
changeset
|
53 |
8186
6a0018cdb2fe
config: add some helper methods
Matt Mackall <mpm@selenic.com>
parents:
8185
diff
changeset
|
54 def __iter__(self): |
6a0018cdb2fe
config: add some helper methods
Matt Mackall <mpm@selenic.com>
parents:
8185
diff
changeset
|
55 for d in self.sections(): |
6a0018cdb2fe
config: add some helper methods
Matt Mackall <mpm@selenic.com>
parents:
8185
diff
changeset
|
56 yield d |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41317
diff
changeset
|
57 |
8193
94246e90081e
config: add section filter to read
Matt Mackall <mpm@selenic.com>
parents:
8192
diff
changeset
|
58 def update(self, src): |
46622
a3dced4b7b04
config: track the "level" of a value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46621
diff
changeset
|
59 current_level = self._current_source_level |
a3dced4b7b04
config: track the "level" of a value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46621
diff
changeset
|
60 current_level += 1 |
a3dced4b7b04
config: track the "level" of a value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46621
diff
changeset
|
61 max_level = self._current_source_level |
19087
7d82ad4b3727
config: discard "%unset" values defined in the other files read in previously
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
17537
diff
changeset
|
62 for s, n in src._unset: |
34357
c41444a39de2
config: use copy-on-write to improve copy performance
Jun Wu <quark@fb.com>
parents:
34131
diff
changeset
|
63 ds = self._data.get(s, None) |
c41444a39de2
config: use copy-on-write to improve copy performance
Jun Wu <quark@fb.com>
parents:
34131
diff
changeset
|
64 if ds is not None and n in ds: |
c41444a39de2
config: use copy-on-write to improve copy performance
Jun Wu <quark@fb.com>
parents:
34131
diff
changeset
|
65 self._data[s] = ds.preparewrite() |
19087
7d82ad4b3727
config: discard "%unset" values defined in the other files read in previously
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
17537
diff
changeset
|
66 del self._data[s][n] |
8193
94246e90081e
config: add section filter to read
Matt Mackall <mpm@selenic.com>
parents:
8192
diff
changeset
|
67 for s in src: |
34357
c41444a39de2
config: use copy-on-write to improve copy performance
Jun Wu <quark@fb.com>
parents:
34131
diff
changeset
|
68 ds = self._data.get(s, None) |
c41444a39de2
config: use copy-on-write to improve copy performance
Jun Wu <quark@fb.com>
parents:
34131
diff
changeset
|
69 if ds: |
c41444a39de2
config: use copy-on-write to improve copy performance
Jun Wu <quark@fb.com>
parents:
34131
diff
changeset
|
70 self._data[s] = ds.preparewrite() |
c41444a39de2
config: use copy-on-write to improve copy performance
Jun Wu <quark@fb.com>
parents:
34131
diff
changeset
|
71 else: |
c41444a39de2
config: use copy-on-write to improve copy performance
Jun Wu <quark@fb.com>
parents:
34131
diff
changeset
|
72 self._data[s] = util.cowsortdict() |
46622
a3dced4b7b04
config: track the "level" of a value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46621
diff
changeset
|
73 for k, v in src._data[s].items(): |
a3dced4b7b04
config: track the "level" of a value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46621
diff
changeset
|
74 value, source, level = v |
a3dced4b7b04
config: track the "level" of a value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46621
diff
changeset
|
75 level += current_level |
a3dced4b7b04
config: track the "level" of a value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46621
diff
changeset
|
76 max_level = max(level, current_level) |
a3dced4b7b04
config: track the "level" of a value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46621
diff
changeset
|
77 self._data[s][k] = (value, source, level) |
a3dced4b7b04
config: track the "level" of a value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46621
diff
changeset
|
78 self._current_source_level = max_level |
46621
d3df397e7a59
config: track "source" along side value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46620
diff
changeset
|
79 |
d3df397e7a59
config: track "source" along side value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46620
diff
changeset
|
80 def _get(self, section, item): |
d3df397e7a59
config: track "source" along side value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46620
diff
changeset
|
81 return self._data.get(section, {}).get(item) |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41317
diff
changeset
|
82 |
8144 | 83 def get(self, section, item, default=None): |
46621
d3df397e7a59
config: track "source" along side value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46620
diff
changeset
|
84 result = self._get(section, item) |
d3df397e7a59
config: track "source" along side value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46620
diff
changeset
|
85 if result is None: |
d3df397e7a59
config: track "source" along side value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46620
diff
changeset
|
86 return default |
d3df397e7a59
config: track "source" along side value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46620
diff
changeset
|
87 return result[0] |
15919
69e792cf7851
config: have a way to backup and restore value in config
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
14696
diff
changeset
|
88 |
46621
d3df397e7a59
config: track "source" along side value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46620
diff
changeset
|
89 def backup(self, section, key): |
17527 | 90 """return a tuple allowing restore to reinstall a previous value |
15919
69e792cf7851
config: have a way to backup and restore value in config
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
14696
diff
changeset
|
91 |
17530 | 92 The main reason we need it is because it handles the "no data" case. |
15919
69e792cf7851
config: have a way to backup and restore value in config
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
14696
diff
changeset
|
93 """ |
69e792cf7851
config: have a way to backup and restore value in config
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
14696
diff
changeset
|
94 try: |
46621
d3df397e7a59
config: track "source" along side value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46620
diff
changeset
|
95 item = self._data[section][key] |
15919
69e792cf7851
config: have a way to backup and restore value in config
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
14696
diff
changeset
|
96 except KeyError: |
46621
d3df397e7a59
config: track "source" along side value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46620
diff
changeset
|
97 return (section, key) |
d3df397e7a59
config: track "source" along side value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46620
diff
changeset
|
98 else: |
d3df397e7a59
config: track "source" along side value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46620
diff
changeset
|
99 return (section, key) + item |
15919
69e792cf7851
config: have a way to backup and restore value in config
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
14696
diff
changeset
|
100 |
8198
cf9accffd0b3
config: getsource -> source
Matt Mackall <mpm@selenic.com>
parents:
8193
diff
changeset
|
101 def source(self, section, item): |
46621
d3df397e7a59
config: track "source" along side value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46620
diff
changeset
|
102 result = self._get(section, item) |
d3df397e7a59
config: track "source" along side value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46620
diff
changeset
|
103 if result is None: |
d3df397e7a59
config: track "source" along side value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46620
diff
changeset
|
104 return b"" |
d3df397e7a59
config: track "source" along side value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46620
diff
changeset
|
105 return result[1] |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41317
diff
changeset
|
106 |
46622
a3dced4b7b04
config: track the "level" of a value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46621
diff
changeset
|
107 def level(self, section, item): |
a3dced4b7b04
config: track the "level" of a value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46621
diff
changeset
|
108 result = self._get(section, item) |
a3dced4b7b04
config: track the "level" of a value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46621
diff
changeset
|
109 if result is None: |
a3dced4b7b04
config: track the "level" of a value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46621
diff
changeset
|
110 return None |
a3dced4b7b04
config: track the "level" of a value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46621
diff
changeset
|
111 return result[2] |
a3dced4b7b04
config: track the "level" of a value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46621
diff
changeset
|
112 |
8144 | 113 def sections(self): |
114 return sorted(self._data.keys()) | |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41317
diff
changeset
|
115 |
51289
7bd7fcc711f2
pytype: drop the last inline type comment
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50929
diff
changeset
|
116 def items(self, section: bytes) -> List[Tuple[bytes, bytes]]: |
48920
b4ab4fd23199
config: remove pycompat.iteritems()
Gregory Szorc <gregory.szorc@gmail.com>
parents:
48890
diff
changeset
|
117 items = self._data.get(section, {}).items() |
46622
a3dced4b7b04
config: track the "level" of a value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46621
diff
changeset
|
118 return [(k, v[0]) for (k, v) in items] |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41317
diff
changeset
|
119 |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
120 def set(self, section, item, value, source=b""): |
48890
f5127b87f160
config: remove conditional asserts
Gregory Szorc <gregory.szorc@gmail.com>
parents:
48875
diff
changeset
|
121 assert not isinstance( |
f5127b87f160
config: remove conditional asserts
Gregory Szorc <gregory.szorc@gmail.com>
parents:
48875
diff
changeset
|
122 section, str |
f5127b87f160
config: remove conditional asserts
Gregory Szorc <gregory.szorc@gmail.com>
parents:
48875
diff
changeset
|
123 ), b'config section may not be unicode strings on Python 3' |
f5127b87f160
config: remove conditional asserts
Gregory Szorc <gregory.szorc@gmail.com>
parents:
48875
diff
changeset
|
124 assert not isinstance( |
f5127b87f160
config: remove conditional asserts
Gregory Szorc <gregory.szorc@gmail.com>
parents:
48875
diff
changeset
|
125 item, str |
f5127b87f160
config: remove conditional asserts
Gregory Szorc <gregory.szorc@gmail.com>
parents:
48875
diff
changeset
|
126 ), b'config item may not be unicode strings on Python 3' |
f5127b87f160
config: remove conditional asserts
Gregory Szorc <gregory.szorc@gmail.com>
parents:
48875
diff
changeset
|
127 assert not isinstance( |
f5127b87f160
config: remove conditional asserts
Gregory Szorc <gregory.szorc@gmail.com>
parents:
48875
diff
changeset
|
128 value, str |
f5127b87f160
config: remove conditional asserts
Gregory Szorc <gregory.szorc@gmail.com>
parents:
48875
diff
changeset
|
129 ), b'config values may not be unicode strings on Python 3' |
8144 | 130 if section not in self: |
34357
c41444a39de2
config: use copy-on-write to improve copy performance
Jun Wu <quark@fb.com>
parents:
34131
diff
changeset
|
131 self._data[section] = util.cowsortdict() |
c41444a39de2
config: use copy-on-write to improve copy performance
Jun Wu <quark@fb.com>
parents:
34131
diff
changeset
|
132 else: |
c41444a39de2
config: use copy-on-write to improve copy performance
Jun Wu <quark@fb.com>
parents:
34131
diff
changeset
|
133 self._data[section] = self._data[section].preparewrite() |
46622
a3dced4b7b04
config: track the "level" of a value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46621
diff
changeset
|
134 self._data[section][item] = (value, source, self._current_source_level) |
8144 | 135 |
46620
7621ab4005bf
config: use a new `alter` method in `fixconfig`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
45942
diff
changeset
|
136 def alter(self, section, key, new_value): |
7621ab4005bf
config: use a new `alter` method in `fixconfig`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
45942
diff
changeset
|
137 """alter a value without altering its source or level |
7621ab4005bf
config: use a new `alter` method in `fixconfig`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
45942
diff
changeset
|
138 |
7621ab4005bf
config: use a new `alter` method in `fixconfig`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
45942
diff
changeset
|
139 This method is meant to be used by `ui.fixconfig` only.""" |
7621ab4005bf
config: use a new `alter` method in `fixconfig`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
45942
diff
changeset
|
140 item = self._data[section][key] |
7621ab4005bf
config: use a new `alter` method in `fixconfig`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
45942
diff
changeset
|
141 size = len(item) |
7621ab4005bf
config: use a new `alter` method in `fixconfig`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
45942
diff
changeset
|
142 new_item = (new_value,) + item[1:] |
7621ab4005bf
config: use a new `alter` method in `fixconfig`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
45942
diff
changeset
|
143 assert len(new_item) == size |
7621ab4005bf
config: use a new `alter` method in `fixconfig`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
45942
diff
changeset
|
144 self._data[section][key] = new_item |
7621ab4005bf
config: use a new `alter` method in `fixconfig`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
45942
diff
changeset
|
145 |
15919
69e792cf7851
config: have a way to backup and restore value in config
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
14696
diff
changeset
|
146 def restore(self, data): |
69e792cf7851
config: have a way to backup and restore value in config
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
14696
diff
changeset
|
147 """restore data returned by self.backup""" |
46621
d3df397e7a59
config: track "source" along side value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46620
diff
changeset
|
148 if len(data) != 2: |
15919
69e792cf7851
config: have a way to backup and restore value in config
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
14696
diff
changeset
|
149 # restore old data |
46621
d3df397e7a59
config: track "source" along side value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46620
diff
changeset
|
150 section, key = data[:2] |
d3df397e7a59
config: track "source" along side value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46620
diff
changeset
|
151 item = data[2:] |
34357
c41444a39de2
config: use copy-on-write to improve copy performance
Jun Wu <quark@fb.com>
parents:
34131
diff
changeset
|
152 self._data[section] = self._data[section].preparewrite() |
46621
d3df397e7a59
config: track "source" along side value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46620
diff
changeset
|
153 self._data[section][key] = item |
15919
69e792cf7851
config: have a way to backup and restore value in config
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
14696
diff
changeset
|
154 else: |
69e792cf7851
config: have a way to backup and restore value in config
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
14696
diff
changeset
|
155 # no data before, remove everything |
69e792cf7851
config: have a way to backup and restore value in config
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
14696
diff
changeset
|
156 section, item = data |
69e792cf7851
config: have a way to backup and restore value in config
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
14696
diff
changeset
|
157 if section in self._data: |
22037
8665c647da6e
config: fix restoreconfig of non existing config
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
21910
diff
changeset
|
158 self._data[section].pop(item, None) |
15919
69e792cf7851
config: have a way to backup and restore value in config
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
14696
diff
changeset
|
159 |
8265
52c5be55af82
config: add parse interface
Matt Mackall <mpm@selenic.com>
parents:
8263
diff
changeset
|
160 def parse(self, src, data, sections=None, remap=None, include=None): |
30349
954002426f78
config: mark parser regexes as bytes explicitly
Augie Fackler <augie@google.com>
parents:
27696
diff
changeset
|
161 sectionre = util.re.compile(br'\[([^\[]+)\]') |
954002426f78
config: mark parser regexes as bytes explicitly
Augie Fackler <augie@google.com>
parents:
27696
diff
changeset
|
162 itemre = util.re.compile(br'([^=\s][^=]*?)\s*=\s*(.*\S|)') |
954002426f78
config: mark parser regexes as bytes explicitly
Augie Fackler <augie@google.com>
parents:
27696
diff
changeset
|
163 contre = util.re.compile(br'\s+(\S|\S.*\S)\s*$') |
954002426f78
config: mark parser regexes as bytes explicitly
Augie Fackler <augie@google.com>
parents:
27696
diff
changeset
|
164 emptyre = util.re.compile(br'(;|#|\s*$)') |
954002426f78
config: mark parser regexes as bytes explicitly
Augie Fackler <augie@google.com>
parents:
27696
diff
changeset
|
165 commentre = util.re.compile(br'(;|#)') |
954002426f78
config: mark parser regexes as bytes explicitly
Augie Fackler <augie@google.com>
parents:
27696
diff
changeset
|
166 unsetre = util.re.compile(br'%unset\s+(\S+)') |
954002426f78
config: mark parser regexes as bytes explicitly
Augie Fackler <augie@google.com>
parents:
27696
diff
changeset
|
167 includere = util.re.compile(br'%include\s+(\S|\S.*\S)\s*$') |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
168 section = b"" |
8144 | 169 item = None |
170 line = 0 | |
9339
9be91129c96e
config: improve code readability
Andrey <py4fun@gmail.com>
parents:
9136
diff
changeset
|
171 cont = False |
8180 | 172 |
34713
e5a2cfc524d4
config: allow remapping the default section
Yuya Nishihara <yuya@tcha.org>
parents:
34454
diff
changeset
|
173 if remap: |
e5a2cfc524d4
config: allow remapping the default section
Yuya Nishihara <yuya@tcha.org>
parents:
34454
diff
changeset
|
174 section = remap.get(section, section) |
e5a2cfc524d4
config: allow remapping the default section
Yuya Nishihara <yuya@tcha.org>
parents:
34454
diff
changeset
|
175 |
9136
31177742f54a
for calls expecting bool args, pass bool instead of int
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
8312
diff
changeset
|
176 for l in data.splitlines(True): |
8144 | 177 line += 1 |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
178 if line == 1 and l.startswith(b'\xef\xbb\xbf'): |
16348
f350021ee32e
config: discard UTF-8 BOM if found
Matt Mackall <mpm@selenic.com>
parents:
15919
diff
changeset
|
179 # Someone set us up the BOM |
f350021ee32e
config: discard UTF-8 BOM if found
Matt Mackall <mpm@selenic.com>
parents:
15919
diff
changeset
|
180 l = l[3:] |
8144 | 181 if cont: |
14642
fdcdb221a922
config: handle comment lines in continuations (issue2854)
Matt Mackall <mpm@selenic.com>
parents:
14486
diff
changeset
|
182 if commentre.match(l): |
fdcdb221a922
config: handle comment lines in continuations (issue2854)
Matt Mackall <mpm@selenic.com>
parents:
14486
diff
changeset
|
183 continue |
8144 | 184 m = contre.match(l) |
185 if m: | |
8193
94246e90081e
config: add section filter to read
Matt Mackall <mpm@selenic.com>
parents:
8192
diff
changeset
|
186 if sections and section not in sections: |
94246e90081e
config: add section filter to read
Matt Mackall <mpm@selenic.com>
parents:
8192
diff
changeset
|
187 continue |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
188 v = self.get(section, item) + b"\n" + m.group(1) |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
189 self.set(section, item, v, b"%s:%d" % (src, line)) |
8144 | 190 continue |
191 item = None | |
9469
7f0f882af23d
config: abort on indented non-continuation lines (issue1829)
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents:
8312
diff
changeset
|
192 cont = False |
8183
2858ab754995
config: allow including other config files
Matt Mackall <mpm@selenic.com>
parents:
8180
diff
changeset
|
193 m = includere.match(l) |
25095
3182965b3971
config: give it an includepaths option for looking for config files
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
22419
diff
changeset
|
194 |
3182965b3971
config: give it an includepaths option for looking for config files
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
22419
diff
changeset
|
195 if m and include: |
3182965b3971
config: give it an includepaths option for looking for config files
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
22419
diff
changeset
|
196 expanded = util.expandpath(m.group(1)) |
45254
3f54242781e9
config: remove now-unused support for "includepaths"
Martin von Zweigbergk <martinvonz@google.com>
parents:
45208
diff
changeset
|
197 try: |
45257
668af67bfd18
config: remove now-unused `abs` argument from `include` callback
Martin von Zweigbergk <martinvonz@google.com>
parents:
45256
diff
changeset
|
198 include(expanded, remap=remap, sections=sections) |
45254
3f54242781e9
config: remove now-unused support for "includepaths"
Martin von Zweigbergk <martinvonz@google.com>
parents:
45208
diff
changeset
|
199 except IOError as inst: |
3f54242781e9
config: remove now-unused support for "includepaths"
Martin von Zweigbergk <martinvonz@google.com>
parents:
45208
diff
changeset
|
200 if inst.errno != errno.ENOENT: |
45894
9dc1351d0b5f
errors: raise ConfigError on failure to parse config file
Martin von Zweigbergk <martinvonz@google.com>
parents:
45777
diff
changeset
|
201 raise error.ConfigError( |
45254
3f54242781e9
config: remove now-unused support for "includepaths"
Martin von Zweigbergk <martinvonz@google.com>
parents:
45208
diff
changeset
|
202 _(b"cannot include %s (%s)") |
45257
668af67bfd18
config: remove now-unused `abs` argument from `include` callback
Martin von Zweigbergk <martinvonz@google.com>
parents:
45256
diff
changeset
|
203 % (expanded, encoding.strtolocal(inst.strerror)), |
45254
3f54242781e9
config: remove now-unused support for "includepaths"
Martin von Zweigbergk <martinvonz@google.com>
parents:
45208
diff
changeset
|
204 b"%s:%d" % (src, line), |
3f54242781e9
config: remove now-unused support for "includepaths"
Martin von Zweigbergk <martinvonz@google.com>
parents:
45208
diff
changeset
|
205 ) |
8183
2858ab754995
config: allow including other config files
Matt Mackall <mpm@selenic.com>
parents:
8180
diff
changeset
|
206 continue |
8144 | 207 if emptyre.match(l): |
208 continue | |
209 m = sectionre.match(l) | |
210 if m: | |
211 section = m.group(1) | |
8298
9542f4c3fa1b
config: make remap actually work
Matt Mackall <mpm@selenic.com>
parents:
8265
diff
changeset
|
212 if remap: |
9542f4c3fa1b
config: make remap actually work
Matt Mackall <mpm@selenic.com>
parents:
8265
diff
changeset
|
213 section = remap.get(section, section) |
8144 | 214 if section not in self: |
34357
c41444a39de2
config: use copy-on-write to improve copy performance
Jun Wu <quark@fb.com>
parents:
34131
diff
changeset
|
215 self._data[section] = util.cowsortdict() |
8144 | 216 continue |
217 m = itemre.match(l) | |
218 if m: | |
219 item = m.group(1) | |
9339
9be91129c96e
config: improve code readability
Andrey <py4fun@gmail.com>
parents:
9136
diff
changeset
|
220 cont = True |
8193
94246e90081e
config: add section filter to read
Matt Mackall <mpm@selenic.com>
parents:
8192
diff
changeset
|
221 if sections and section not in sections: |
94246e90081e
config: add section filter to read
Matt Mackall <mpm@selenic.com>
parents:
8192
diff
changeset
|
222 continue |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
223 self.set(section, item, m.group(2), b"%s:%d" % (src, line)) |
8144 | 224 continue |
8184
9189afe1eba3
config: add %unset name support
Matt Mackall <mpm@selenic.com>
parents:
8183
diff
changeset
|
225 m = unsetre.match(l) |
9189afe1eba3
config: add %unset name support
Matt Mackall <mpm@selenic.com>
parents:
8183
diff
changeset
|
226 if m: |
9189afe1eba3
config: add %unset name support
Matt Mackall <mpm@selenic.com>
parents:
8183
diff
changeset
|
227 name = m.group(1) |
8193
94246e90081e
config: add section filter to read
Matt Mackall <mpm@selenic.com>
parents:
8192
diff
changeset
|
228 if sections and section not in sections: |
94246e90081e
config: add section filter to read
Matt Mackall <mpm@selenic.com>
parents:
8192
diff
changeset
|
229 continue |
13031
3da456d0c885
code style: prefer 'is' and 'is not' tests with singletons
Martin Geisler <mg@aragost.com>
parents:
11292
diff
changeset
|
230 if self.get(section, name) is not None: |
34454
0efdfb57b05c
config: add a missing preparewrite() call
Jun Wu <quark@fb.com>
parents:
34357
diff
changeset
|
231 self._data[section] = self._data[section].preparewrite() |
8184
9189afe1eba3
config: add %unset name support
Matt Mackall <mpm@selenic.com>
parents:
8183
diff
changeset
|
232 del self._data[section][name] |
19087
7d82ad4b3727
config: discard "%unset" values defined in the other files read in previously
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
17537
diff
changeset
|
233 self._unset.append((section, name)) |
8184
9189afe1eba3
config: add %unset name support
Matt Mackall <mpm@selenic.com>
parents:
8183
diff
changeset
|
234 continue |
9189afe1eba3
config: add %unset name support
Matt Mackall <mpm@selenic.com>
parents:
8183
diff
changeset
|
235 |
45777
0883413e09bc
config: move message about leading spaces in config to config.py
Martin von Zweigbergk <martinvonz@google.com>
parents:
45257
diff
changeset
|
236 message = l.rstrip() |
0883413e09bc
config: move message about leading spaces in config to config.py
Martin von Zweigbergk <martinvonz@google.com>
parents:
45257
diff
changeset
|
237 if l.startswith(b' '): |
0883413e09bc
config: move message about leading spaces in config to config.py
Martin von Zweigbergk <martinvonz@google.com>
parents:
45257
diff
changeset
|
238 message = b"unexpected leading whitespace: %s" % message |
45894
9dc1351d0b5f
errors: raise ConfigError on failure to parse config file
Martin von Zweigbergk <martinvonz@google.com>
parents:
45777
diff
changeset
|
239 raise error.ConfigError(message, (b"%s:%d" % (src, line))) |
8265
52c5be55af82
config: add parse interface
Matt Mackall <mpm@selenic.com>
parents:
8263
diff
changeset
|
240 |
52c5be55af82
config: add parse interface
Matt Mackall <mpm@selenic.com>
parents:
8263
diff
changeset
|
241 def read(self, path, fp=None, sections=None, remap=None): |
46622
a3dced4b7b04
config: track the "level" of a value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46621
diff
changeset
|
242 self.new_source() |
8265
52c5be55af82
config: add parse interface
Matt Mackall <mpm@selenic.com>
parents:
8263
diff
changeset
|
243 if not fp: |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
244 fp = util.posixfile(path, b'rb') |
45942
89a2afe31e82
formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents:
45894
diff
changeset
|
245 assert ( |
89a2afe31e82
formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents:
45894
diff
changeset
|
246 getattr(fp, 'mode', 'rb') == 'rb' |
89a2afe31e82
formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents:
45894
diff
changeset
|
247 ), b'config files must be opened in binary mode, got fp=%r mode=%r' % ( |
89a2afe31e82
formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents:
45894
diff
changeset
|
248 fp, |
89a2afe31e82
formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents:
45894
diff
changeset
|
249 fp.mode, |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41317
diff
changeset
|
250 ) |
45208
f7f142d74df3
config: pass both relative and absolute paths to `include` callback
Martin von Zweigbergk <martinvonz@google.com>
parents:
43506
diff
changeset
|
251 |
45256
83ca8d6f3206
config: re-calculate absolute %include path in `include` callback
Martin von Zweigbergk <martinvonz@google.com>
parents:
45254
diff
changeset
|
252 dir = os.path.dirname(path) |
83ca8d6f3206
config: re-calculate absolute %include path in `include` callback
Martin von Zweigbergk <martinvonz@google.com>
parents:
45254
diff
changeset
|
253 |
45257
668af67bfd18
config: remove now-unused `abs` argument from `include` callback
Martin von Zweigbergk <martinvonz@google.com>
parents:
45256
diff
changeset
|
254 def include(rel, remap, sections): |
45256
83ca8d6f3206
config: re-calculate absolute %include path in `include` callback
Martin von Zweigbergk <martinvonz@google.com>
parents:
45254
diff
changeset
|
255 abs = os.path.normpath(os.path.join(dir, rel)) |
45208
f7f142d74df3
config: pass both relative and absolute paths to `include` callback
Martin von Zweigbergk <martinvonz@google.com>
parents:
43506
diff
changeset
|
256 self.read(abs, remap=remap, sections=sections) |
46622
a3dced4b7b04
config: track the "level" of a value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46621
diff
changeset
|
257 # anything after the include has a higher level |
a3dced4b7b04
config: track the "level" of a value
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
46621
diff
changeset
|
258 self.new_source() |
45208
f7f142d74df3
config: pass both relative and absolute paths to `include` callback
Martin von Zweigbergk <martinvonz@google.com>
parents:
43506
diff
changeset
|
259 |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41317
diff
changeset
|
260 self.parse( |
45208
f7f142d74df3
config: pass both relative and absolute paths to `include` callback
Martin von Zweigbergk <martinvonz@google.com>
parents:
43506
diff
changeset
|
261 path, fp.read(), sections=sections, remap=remap, include=include |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41317
diff
changeset
|
262 ) |