Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagesmc
Path: blob/master/src/sage/dev/config.py
8815 views
1
r"""
2
Configuration wrapper
3
4
This module provides a wrapper for the ``devrc`` file in ``DOT_SAGE`` directory
5
which stores the configuration for :class:`SageDev`.
6
7
AUTHORS:
8
9
- David Roe, Frej Drejhammar, Julian Rueth, Martin Raum, Nicolas M. Thiery, R.
10
Andrew Ohana, Robert Bradshaw, Timo Kluck: initial version
11
12
"""
13
#*****************************************************************************
14
# Copyright (C) 2013 David Roe <[email protected]>
15
# Frej Drejhammar <[email protected]>
16
# Julian Rueth <[email protected]>
17
# Martin Raum <[email protected]>
18
# Nicolas M. Thiery <[email protected]>
19
# R. Andrew Ohana <[email protected]>
20
# Robert Bradshaw <[email protected]>
21
# Timo Kluck <[email protected]>
22
#
23
# Distributed under the terms of the GNU General Public License (GPL)
24
# as published by the Free Software Foundation; either version 2 of
25
# the License, or (at your option) any later version.
26
# http://www.gnu.org/licenses/
27
#*****************************************************************************
28
29
import collections
30
import os
31
import ConfigParser as configparser
32
33
from sage.env import DOT_SAGE
34
35
DEVRC = os.path.join(DOT_SAGE, 'devrc')
36
37
class Config(collections.MutableMapping):
38
r"""
39
Wrapper for the ``devrc`` file storing the configuration for
40
:class:`SageDev`.
41
42
INPUT:
43
44
- ``devrc`` -- a string (default: the absolute path of the ``devrc`` file
45
in ``DOT_SAGE``)
46
47
EXAMPLES::
48
49
sage: from sage.dev.config import Config
50
sage: Config() # random output, the output depends on the user's config
51
Config('''
52
[trac]
53
username = doctest
54
''')
55
"""
56
def __init__(self, devrc = DEVRC):
57
r"""
58
Initialization.
59
60
TESTS::
61
62
sage: from sage.dev.config import Config
63
sage: type(Config())
64
<class 'sage.dev.config.Config'>
65
"""
66
self._config = configparser.ConfigParser()
67
self._devrc = devrc
68
self._read_config()
69
self._doctest_config = False
70
71
def __repr__(self):
72
r"""
73
Return a printable representation of this object.
74
75
EXAMPLES::
76
77
sage: from sage.dev.test.config import DoctestConfig
78
sage: c = DoctestConfig()
79
sage: repr(c)
80
"Config('''\n[trac]\n...\n[UI]\n...\n[git]...\n[sagedev]\n''')"
81
"""
82
config = "".join([ "[%s]\n"%s +
83
"".join(["%s = %s\n"%(o,self[s][o]) for o in self[s] ])
84
for s in self ])
85
return "Config('''\n"+ config +"''')"
86
87
def _read_config(self):
88
r"""
89
Read the configuration from disk.
90
91
EXAMPLES::
92
93
sage: from sage.dev.test.config import DoctestConfig
94
sage: c = DoctestConfig()
95
96
sage: from sage.dev.config import Config
97
sage: c2 = Config(c._devrc)
98
sage: c["trac"]["username"] = "foo"
99
sage: c2
100
Config('''
101
[trac]
102
username = doctest
103
ticket_cache = ...
104
[UI]
105
...
106
[git]
107
...
108
[sagedev]
109
''')
110
sage: c._write_config()
111
sage: c2._read_config()
112
sage: c2
113
Config('''
114
[trac]
115
username = foo
116
ticket_cache = ...
117
[UI]
118
...
119
[git]
120
...
121
[sagedev]
122
''')
123
"""
124
if os.path.exists(self._devrc):
125
self._config.read(self._devrc)
126
127
def _write_config(self):
128
r"""
129
Write the configuration to disk.
130
131
EXAMPLES::
132
133
sage: from sage.dev.test.config import DoctestConfig
134
sage: c = DoctestConfig()
135
sage: os.unlink(c._devrc)
136
sage: os.path.exists(c._devrc)
137
False
138
sage: c._write_config()
139
sage: os.path.exists(c._devrc)
140
True
141
"""
142
import sage.doctest
143
assert not sage.doctest.DOCTEST_MODE or self._devrc != DEVRC, "attempt to overwrite devrc in doctest"
144
145
with open(self._devrc, 'w') as F:
146
self._config.write(F)
147
# set the configuration file to read only by this user,
148
# because it may contain the trac password
149
os.chmod(self._devrc, 0600)
150
151
def __getitem__(self, section):
152
r"""
153
Return the configurations in ``section``.
154
155
EXAMPLES::
156
157
sage: from sage.dev.test.config import DoctestConfig
158
sage: c = DoctestConfig()
159
sage: c['trac']
160
IndexableForSection('''
161
username = doctest
162
ticket_cache = ...
163
''')
164
sage: c['tig']
165
Traceback (most recent call last):
166
...
167
KeyError: 'tig'
168
"""
169
if not section in self:
170
raise KeyError(section)
171
172
class IndexableForSection(collections.MutableMapping):
173
r"""
174
A section of a :class:`Config`.
175
176
TESTS::
177
178
sage: from sage.dev.test.config import DoctestConfig
179
sage: c = DoctestConfig()
180
sage: c["trac"]
181
IndexableForSection('''
182
username = doctest
183
ticket_cache = ...
184
''')
185
"""
186
def __init__(this, section):
187
r"""
188
Initialization.
189
190
TESTS::
191
192
sage: from sage.dev.test.config import DoctestConfig
193
sage: c = DoctestConfig()
194
sage: type(c['trac'])
195
<class 'sage.dev.config.IndexableForSection'>
196
"""
197
this._section = section
198
199
def __repr__(this):
200
r"""
201
Return a printable representation of this section.
202
203
TESTS::
204
205
sage: from sage.dev.test.config import DoctestConfig
206
sage: c = DoctestConfig()
207
sage: c["trac"]
208
IndexableForSection('''
209
username = doctest
210
ticket_cache = ...
211
''')
212
"""
213
return "IndexableForSection('''\n"+"\n".join(["%s = %s"%(o,this[o]) for o in this])+"\n''')"
214
215
def __getitem__(this, option):
216
r"""
217
Return the value for ``option`` or raise a ``KeyError`` if
218
this option is not set.
219
220
TESTS::
221
222
sage: from sage.dev.test.config import DoctestConfig
223
sage: c = DoctestConfig()
224
sage: c["trac"]["username"]
225
'doctest'
226
sage: c["trac"]["nousername"]
227
Traceback (most recent call last):
228
...
229
KeyError: 'nousername'
230
"""
231
try:
232
return self._config.get(this._section, option)
233
except configparser.NoOptionError:
234
raise KeyError(option)
235
236
def __iter__(this):
237
r"""
238
Return an iterator over the options in this section.
239
240
TESTS::
241
242
sage: from sage.dev.test.config import DoctestConfig
243
sage: c = DoctestConfig()
244
sage: list(c["trac"])
245
['username', 'ticket_cache']
246
"""
247
return iter(self._config.options(this._section))
248
249
def __setitem__(this, option, value):
250
r"""
251
Set ``option`` to ``value``.
252
253
TESTS::
254
255
sage: from sage.dev.test.config import DoctestConfig
256
sage: c = DoctestConfig()
257
sage: c["trac"]["username"] = "foo"
258
sage: c["trac"]["username"]
259
'foo'
260
"""
261
self._config.set(this._section, option, value)
262
self._write_config()
263
264
def __delitem__(this, option):
265
r"""
266
Remove ``option`` from this section.
267
268
TESTS::
269
270
sage: from sage.dev.test.config import DoctestConfig
271
sage: c = DoctestConfig()
272
sage: del(c["trac"]["username"])
273
sage: c["trac"]["username"]
274
Traceback (most recent call last):
275
...
276
KeyError: 'username'
277
"""
278
self._config.remove_option(this._section, option)
279
self._write_config()
280
281
def __len__(this):
282
r"""
283
Return the number of options in this section.
284
285
TESTS::
286
287
sage: from sage.dev.test.config import DoctestConfig
288
sage: c = DoctestConfig()
289
sage: len(c["trac"])
290
2
291
"""
292
return len(self._config.options(this._section))
293
294
def __contains__(this, option):
295
r"""
296
Return whether this section contains ``options``.
297
298
TESTS::
299
300
sage: from sage.dev.test.config import DoctestConfig
301
sage: c = DoctestConfig()
302
sage: "username" in c["trac"]
303
True
304
"""
305
return option in self._config.options(this._section)
306
307
return IndexableForSection(section)
308
309
def __contains__(self, section):
310
r"""
311
Returns ``True`` if ``section`` is in the configuration.
312
313
EXAMPLES::
314
315
sage: from sage.dev.test.config import DoctestConfig
316
sage: c = DoctestConfig()
317
sage: 'trac' in c
318
True
319
sage: 'nottrac' in c
320
False
321
"""
322
return section in self._config.sections()
323
324
def __iter__(self):
325
r"""
326
Return an iterator over the section names.
327
328
EXAMPLES::
329
330
sage: from sage.dev.test.config import DoctestConfig
331
sage: c = DoctestConfig()
332
sage: list(c)
333
['trac', 'UI', 'git', 'sagedev']
334
"""
335
return iter(self._config.sections())
336
337
def __setitem__(self, section, dictionary):
338
r"""
339
Copy the options from ``dictionary`` to ``section``.
340
341
EXAMPLES::
342
343
sage: from sage.dev.test.config import DoctestConfig
344
sage: c = DoctestConfig()
345
sage: c["foo"] = {"foo":"foo"}
346
sage: c["foo"]["foo"]
347
'foo'
348
"""
349
was_empty = True
350
351
if self._config.has_section(section):
352
was_empty = len(self[section]) == 0
353
self._config.remove_section(section)
354
self._config.add_section(section)
355
for option, value in dictionary.iteritems():
356
self._config.set(section, option, value)
357
358
if not was_empty or len(dictionary) != 0:
359
self._write_config()
360
361
def __len__(self):
362
r"""
363
Get the number of sections in the configuration.
364
365
EXAMPLES::
366
367
sage: from sage.dev.test.config import DoctestConfig
368
sage: c = DoctestConfig()
369
sage: len(c)
370
4
371
"""
372
return len(self._config.sections())
373
374
def __delitem__(self, section):
375
r"""
376
Remove ``section`` from the configuration
377
378
EXAMPLES::
379
380
sage: from sage.dev.test.config import DoctestConfig
381
sage: c = DoctestConfig()
382
sage: c
383
Config('''
384
[trac]
385
username = doctest
386
ticket_cache = ...
387
[UI]
388
log_level = 1
389
[git]
390
ssh_key_set = True
391
repository_anonymous = remote_repository_undefined
392
repository = remote_repository_undefined
393
src = ...
394
dot_git = ...
395
user_email_set = True
396
[sagedev]
397
''')
398
sage: del c['git']
399
sage: c
400
Config('''
401
[trac]
402
username = doctest
403
ticket_cache = ...
404
[UI]
405
log_level = 1
406
[sagedev]
407
''')
408
"""
409
self._config.remove_section(section)
410
self._write_config()
411
412