##// END OF EJS Templates
Added new tests for config.loader and configurable.
Brian Granger -
Show More
@@ -1,5 +1,3 b''
1 # -*- coding: utf-8 -*-
2 # coding: utf-8
3 """A simple configuration system.
1 """A simple configuration system.
4
2
5 Authors
3 Authors
@@ -20,7 +18,6 b' Authors'
20 #-----------------------------------------------------------------------------
18 #-----------------------------------------------------------------------------
21
19
22 import __builtin__
20 import __builtin__
23 import os
24 import sys
21 import sys
25
22
26 from IPython.external import argparse
23 from IPython.external import argparse
@@ -324,7 +321,7 b' class KeyValueConfigLoader(CommandLineConfigLoader):'
324 A list that has the form of sys.argv[1:] which has unicode
321 A list that has the form of sys.argv[1:] which has unicode
325 elements of the form u"key=value". If this is None (default),
322 elements of the form u"key=value". If this is None (default),
326 then sys.argv[1:] will be used.
323 then sys.argv[1:] will be used.
327 class : (list, tuple) of Configurables
324 classes : (list, tuple) of Configurables
328 A sequence of Configurable classes that will be used to map
325 A sequence of Configurable classes that will be used to map
329 shortnames to longnames.
326 shortnames to longnames.
330
327
@@ -357,31 +354,31 b' class KeyValueConfigLoader(CommandLineConfigLoader):'
357 A list that has the form of sys.argv[1:] which has unicode
354 A list that has the form of sys.argv[1:] which has unicode
358 elements of the form u"key=value". If this is None (default),
355 elements of the form u"key=value". If this is None (default),
359 then self.argv will be used.
356 then self.argv will be used.
360 class : (list, tuple) of Configurables
357 classes : (list, tuple) of Configurables
361 A sequence of Configurable classes that will be used to map
358 A sequence of Configurable classes that will be used to map
362 shortnames to longnames.
359 shortnames to longnames.
363 """
360 """
361 from IPython.config.configurable import Configurable
362
364 self.clear()
363 self.clear()
365 if argv is None:
364 if argv is None:
366 argv = self.argv
365 argv = self.argv
367 if classes is None:
366 if classes is None:
368 classes = self.classes
367 classes = self.classes
369
368
370 # print argv
369 # Create the mapping between shortnames and longnames.
371
372 shortnames = {}
370 shortnames = {}
373 for cls in classes:
371 for cls in classes:
374 sn = cls.class_get_shortnames()
372 if issubclass(cls, Configurable):
375 # Check for duplicate shortnames and raise if found.
373 sn = cls.class_get_shortnames()
376 for k, v in sn.items():
374 # Check for duplicate shortnames and raise if found.
377 if k in shortnames:
375 for k, v in sn.items():
378 raise KeyError(
376 if k in shortnames:
379 "duplicate shortname: %s and %s both use the shortname: %s" %\
377 raise KeyError(
380 (v, shortnames[k], k)
378 'Duplicate shortname: both %s and %s use the shortname: "%s"' %\
381 )
379 (v, shortnames[k], k)
382 shortnames.update(sn)
380 )
383
381 shortnames.update(sn)
384 # print shortnames
385
382
386 for item in argv:
383 for item in argv:
387 pair = tuple(item.split("="))
384 pair = tuple(item.split("="))
@@ -393,8 +390,14 b' class KeyValueConfigLoader(CommandLineConfigLoader):'
393 lhs = shortnames[lhs]
390 lhs = shortnames[lhs]
394 exec_str = 'self.config.' + lhs + '=' + rhs
391 exec_str = 'self.config.' + lhs + '=' + rhs
395 try:
392 try:
393 # Try to see if regular Python syntax will work. This
394 # won't handle strings as the quote marks are removed
395 # by the system shell.
396 exec exec_str in locals(), globals()
396 exec exec_str in locals(), globals()
397 except (NameError, SyntaxError):
397 except (NameError, SyntaxError):
398 # This case happens if the rhs is a string but without
399 # the quote marks. We add the quote marks and see if
400 # it succeeds. If it still fails, we let it raise.
398 exec_str = 'self.config.' + lhs + '="' + rhs + '"'
401 exec_str = 'self.config.' + lhs + '="' + rhs + '"'
399 exec exec_str in locals(), globals()
402 exec exec_str in locals(), globals()
400 return self.config
403 return self.config
@@ -35,19 +35,26 b' from IPython.config.loader import Config'
35
35
36
36
37 class MyConfigurable(Configurable):
37 class MyConfigurable(Configurable):
38 a = Int(1, config=True)
38 a = Int(1, config=True, shortname="a", help="The integer a.")
39 b = Float(1.0, config=True)
39 b = Float(1.0, config=True, shortname="b", help="The integer b.")
40 c = Str('no config')
40 c = Str('no config')
41
41
42
42
43 mc_help=u"""MyConfigurable options
44 ----------------------
45 MyConfigurable.a : Int (shortname=a)
46 The integer a.
47 MyConfigurable.b : Float (shortname=b)
48 The integer b."""
49
43 class Foo(Configurable):
50 class Foo(Configurable):
44 a = Int(0, config=True)
51 a = Int(0, config=True, shortname="a", help="The integer a.")
45 b = Str('nope', config=True)
52 b = Str('nope', config=True)
46
53
47
54
48 class Bar(Foo):
55 class Bar(Foo):
49 b = Str('gotit', config=False)
56 b = Str('gotit', config=False, shortname="b", help="The string b.")
50 c = Float(config=True)
57 c = Float(config=True, shortname="c", help="The string c.")
51
58
52
59
53 class TestConfigurableConfig(TestCase):
60 class TestConfigurableConfig(TestCase):
@@ -122,3 +129,15 b' class TestConfigurableConfig(TestCase):'
122 self.assertEquals(c.a, 2)
129 self.assertEquals(c.a, 2)
123 self.assertEquals(c.b, 'and')
130 self.assertEquals(c.b, 'and')
124 self.assertEquals(c.c, 20.0)
131 self.assertEquals(c.c, 20.0)
132
133 def test_shortnames(self):
134 sn = MyConfigurable.class_get_shortnames()
135 self.assertEquals(sn, {'a': 'MyConfigurable.a', 'b': 'MyConfigurable.b'})
136 sn = Foo.class_get_shortnames()
137 self.assertEquals(sn, {'a': 'Foo.a'})
138 sn = Bar.class_get_shortnames()
139 self.assertEquals(sn, {'a': 'Bar.a', 'c': 'Bar.c'})
140
141 def test_help(self):
142 self.assertEquals(MyConfigurable.class_get_help(), mc_help)
143
@@ -24,6 +24,8 b' import os'
24 from tempfile import mkstemp
24 from tempfile import mkstemp
25 from unittest import TestCase
25 from unittest import TestCase
26
26
27 from IPython.utils.traitlets import Int, Unicode
28 from IPython.config.configurable import Configurable
27 from IPython.config.loader import (
29 from IPython.config.loader import (
28 Config,
30 Config,
29 PyFileConfigLoader,
31 PyFileConfigLoader,
@@ -123,6 +125,24 b' class TestKeyValueCL(TestCase):'
123 self.assertEquals(config.Foo.Bam.value, range(10))
125 self.assertEquals(config.Foo.Bam.value, range(10))
124 self.assertEquals(config.D.C.value, 'hi there')
126 self.assertEquals(config.D.C.value, 'hi there')
125
127
128 def test_shortname(self):
129 class Foo(Configurable):
130 i = Int(0, config=True, shortname="i")
131 s = Unicode('hi', config=True, shortname="s")
132 cl = KeyValueConfigLoader()
133 config = cl.load_config(["i=20", "s=there"], classes=[Foo])
134 self.assertEquals(config.Foo.i, 20)
135 self.assertEquals(config.Foo.s, "there")
136
137 def test_duplicate(self):
138 class Foo(Configurable):
139 i = Int(0, config=True, shortname="i")
140 class Bar(Configurable):
141 i = Int(0, config=True, shortname="i")
142 cl = KeyValueConfigLoader()
143 self.assertRaises(KeyError, cl.load_config, ["i=20", "s=there"], classes=[Foo, Bar])
144
145
126 class TestConfig(TestCase):
146 class TestConfig(TestCase):
127
147
128 def test_setget(self):
148 def test_setget(self):
General Comments 0
You need to be logged in to leave comments. Login now