Skip to content

Commit 95c5b27

Browse files
author
osimons
committedDec 4, 2007
Updated the trac.config.Configuration.get*() and Section.get*() methods to be more consistent in their input and return values - with recommended default of string or 'base type' signified by method name, and always looking to return the 'base type'.
Introduces a `Configuration.has_option(section, option)` that checks for the existence of an option somewhere in project trac.ini file, inherited trac.ini file, or in the options registry. Updated method documentation + added some tests. Closing #4977. git-svn-id: http://trac.edgewall.org/intertrac/log:/trunk@6280 af82e41b-90c4-0310-8c96-b1721e28e2e2
1 parent 5d73c6d commit 95c5b27

File tree

2 files changed

+84
-18
lines changed

2 files changed

+84
-18
lines changed
 

‎trac/config.py

+63-17
Original file line numberDiff line numberDiff line change
@@ -60,38 +60,47 @@ def __getitem__(self, name):
6060
def __repr__(self):
6161
return '<%s %r>' % (self.__class__.__name__, self.filename)
6262

63-
def get(self, section, name, default=None):
64-
"""Return the value of the specified option."""
63+
def get(self, section, name, default=''):
64+
"""Return the value of the specified option.
65+
66+
Valid default input is a string. Returns a string.
67+
"""
6568
return self[section].get(name, default)
6669

67-
def getbool(self, section, name, default=None):
70+
def getbool(self, section, name, default=''):
6871
"""Return the specified option as boolean value.
6972
7073
If the value of the option is one of "yes", "true", "enabled", "on",
7174
or "1", this method wll return `True`, otherwise `False`.
7275
76+
Valid default input is a string or a bool. Returns a bool.
77+
7378
(since Trac 0.9.3, "enabled" added in 0.11)
7479
"""
7580
return self[section].getbool(name, default)
7681

77-
def getint(self, section, name, default=None):
82+
def getint(self, section, name, default=''):
7883
"""Return the value of the specified option as integer.
7984
8085
If the specified option can not be converted to an integer, a
8186
`ConfigurationError` exception is raised.
8287
88+
Valid default input is a string or an int. Returns an int.
89+
8390
(since Trac 0.10)
8491
"""
8592
return self[section].getint(name, default)
8693

87-
def getlist(self, section, name, default=None, sep=',', keep_empty=False):
94+
def getlist(self, section, name, default='', sep=',', keep_empty=False):
8895
"""Return a list of values that have been specified as a single
8996
comma-separated option.
9097
9198
A different separator can be specified using the `sep` parameter. If
9299
the `keep_empty` parameter is set to `True`, empty elements are
93100
included in the list.
94101
102+
Valid default input is a string or a list. Returns a string.
103+
95104
(since Trac 0.10)
96105
"""
97106
return self[section].getlist(name, default, sep, keep_empty)
@@ -136,6 +145,27 @@ def sections(self):
136145
parent = parent.parent
137146
return sorted(sections)
138147

148+
def has_option(self, section, option):
149+
"""Returns True if option exists in section in either project or
150+
parent trac.ini, or available through the Option registry.
151+
152+
(since Trac 0.11)
153+
"""
154+
# Check project trac.ini
155+
for file_option, val in self.options(section):
156+
if file_option == option:
157+
return True
158+
# Check parent trac.ini
159+
if self.parent:
160+
for parent_option, val in self.parent.options(section):
161+
if parent_option == option:
162+
return True
163+
# Check the registry
164+
if (section, option) in Option.registry:
165+
return True
166+
# Not found
167+
return False
168+
139169
def save(self):
140170
"""Write the configuration options to the primary file."""
141171
if not self.filename:
@@ -238,8 +268,11 @@ def __iter__(self):
238268
def __repr__(self):
239269
return '<Section [%s]>' % (self.name)
240270

241-
def get(self, name, default=None):
242-
"""Return the value of the specified option."""
271+
def get(self, name, default=''):
272+
"""Return the value of the specified option.
273+
274+
Valid default input is a string. Returns a string.
275+
"""
243276
if self.config.parser.has_option(self.name, name):
244277
value = self.config.parser.get(self.name, name)
245278
elif self.config.parent:
@@ -250,44 +283,55 @@ def get(self, name, default=None):
250283
value = option.default or default
251284
else:
252285
value = default
253-
if value is None:
254-
return ''
255-
return to_unicode(value)
286+
if not value:
287+
return u''
288+
elif isinstance(value, basestring):
289+
return to_unicode(value)
290+
else:
291+
return value
256292

257-
def getbool(self, name, default=None):
293+
def getbool(self, name, default=''):
258294
"""Return the value of the specified option as boolean.
259295
260296
This method returns `True` if the option value is one of "yes", "true",
261297
"enabled", "on", or "1", ignoring case. Otherwise `False` is returned.
298+
299+
Valid default input is a string or a bool. Returns a bool.
262300
"""
263301
value = self.get(name, default)
264302
if isinstance(value, basestring):
265303
value = value.lower() in _TRUE_VALUES
266304
return bool(value)
267305

268-
def getint(self, name, default=None):
306+
def getint(self, name, default=''):
269307
"""Return the value of the specified option as integer.
270308
271309
If the specified option can not be converted to an integer, a
272310
`ConfigurationError` exception is raised.
311+
312+
Valid default input is a string or an int. Returns an int.
273313
"""
274314
value = self.get(name, default)
275-
if value == '':
276-
return default
315+
if not value:
316+
return 0
277317
try:
278318
return int(value)
279319
except ValueError:
280320
raise ConfigurationError('expected integer, got %s' % repr(value))
281321

282-
def getlist(self, name, default=None, sep=',', keep_empty=True):
322+
def getlist(self, name, default='', sep=',', keep_empty=True):
283323
"""Return a list of values that have been specified as a single
284324
comma-separated option.
285325
286326
A different separator can be specified using the `sep` parameter. If
287-
the `skip_empty` parameter is set to `True`, empty elements are omitted
327+
the `keep_empty` parameter is set to `False`, empty elements are omitted
288328
from the list.
329+
330+
Valid default input is a string or a list. Returns a list.
289331
"""
290332
value = self.get(name, default)
333+
if not value:
334+
return []
291335
if isinstance(value, basestring):
292336
items = [item.strip() for item in value.split(sep)]
293337
else:
@@ -296,9 +340,11 @@ def getlist(self, name, default=None, sep=',', keep_empty=True):
296340
items = filter(None, items)
297341
return items
298342

299-
def getpath(self, name, default=None):
343+
def getpath(self, name, default=''):
300344
"""Return the value of the specified option as a path name, relative to
301345
the location of the configuration file the option is defined in.
346+
347+
Valid default input is a string. Returns a string with normalised path.
302348
"""
303349
if self.config.parser.has_option(self.name, name):
304350
path = self.config.parser.get(self.name, name)

‎trac/tests/config.py

+21-1
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ class Foo(object):
6868
def test_default_int(self):
6969
config = self._read()
7070
self.assertRaises(ConfigurationError, config.getint, 'a', 'option', 'b')
71-
self.assertEquals(None, config.getint('a', 'option'))
71+
self.assertEquals(0, config.getint('a', 'option'))
7272
self.assertEquals(1, config.getint('a', 'option', '1'))
7373
self.assertEquals(1, config.getint('a', 'option', 1))
7474

@@ -82,24 +82,37 @@ def test_read_and_get(self):
8282
config = self._read()
8383
self.assertEquals('x', config.get('a', 'option'))
8484
self.assertEquals('x', config.get('a', 'option', 'y'))
85+
self.assertEquals('y', config.get('b', 'option2', 'y'))
8586

8687
def test_read_and_getbool(self):
8788
self._write(['[a]', 'option = yes'])
8889
config = self._read()
8990
self.assertEquals(True, config.getbool('a', 'option'))
9091
self.assertEquals(True, config.getbool('a', 'option', False))
92+
self.assertEquals(False, config.getbool('b', 'option2'))
93+
self.assertEquals(False, config.getbool('b', 'option2', False))
94+
self.assertEquals(False, config.getbool('b', 'option2', 'disabled'))
9195

9296
def test_read_and_getint(self):
9397
self._write(['[a]', 'option = 42'])
9498
config = self._read()
9599
self.assertEquals(42, config.getint('a', 'option'))
96100
self.assertEquals(42, config.getint('a', 'option', 25))
101+
self.assertEquals(0, config.getint('b', 'option2'))
102+
self.assertEquals(25, config.getint('b', 'option2', 25))
103+
self.assertEquals(25, config.getint('b', 'option2', '25'))
97104

98105
def test_read_and_getlist(self):
99106
self._write(['[a]', 'option = foo, bar, baz'])
100107
config = self._read()
101108
self.assertEquals(['foo', 'bar', 'baz'],
102109
config.getlist('a', 'option'))
110+
self.assertEquals([],
111+
config.getlist('b', 'option2'))
112+
self.assertEquals(['foo', 'bar', 'baz'],
113+
config.getlist('b', 'option2', ['foo', 'bar', 'baz']))
114+
self.assertEquals(['foo', 'bar', 'baz'],
115+
config.getlist('b', 'option2', 'foo, bar, baz'))
103116

104117
def test_read_and_getlist_sep(self):
105118
self._write(['[a]', 'option = foo | bar | baz'])
@@ -159,6 +172,13 @@ def test_options(self):
159172
self.assertEquals(('option', 'y'), iter(config.options('b')).next())
160173
self.assertRaises(StopIteration, iter(config.options('c')).next)
161174

175+
def test_has_option(self):
176+
config = self._read()
177+
self.assertEquals(False, config.has_option('a', 'option'))
178+
self._write(['[a]', 'option = x'])
179+
config = self._read()
180+
self.assertEquals(True, config.has_option('a', 'option'))
181+
162182
def test_reparse(self):
163183
self._write(['[a]', 'option = x'])
164184
config = self._read()

0 commit comments

Comments
 (0)
Please sign in to comment.