From e766cc8ce1fb4bc0ad65dc4d99342285bc7a08b6 2011-04-24 00:42:02 From: Brian Granger Date: 2011-04-24 00:42:02 Subject: [PATCH] Added new tests for config.loader and configurable. --- diff --git a/IPython/config/loader.py b/IPython/config/loader.py index 720aef5..01fa26e 100644 --- a/IPython/config/loader.py +++ b/IPython/config/loader.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- -# coding: utf-8 """A simple configuration system. Authors @@ -20,7 +18,6 @@ Authors #----------------------------------------------------------------------------- import __builtin__ -import os import sys from IPython.external import argparse @@ -324,7 +321,7 @@ class KeyValueConfigLoader(CommandLineConfigLoader): A list that has the form of sys.argv[1:] which has unicode elements of the form u"key=value". If this is None (default), then sys.argv[1:] will be used. - class : (list, tuple) of Configurables + classes : (list, tuple) of Configurables A sequence of Configurable classes that will be used to map shortnames to longnames. @@ -357,31 +354,31 @@ class KeyValueConfigLoader(CommandLineConfigLoader): A list that has the form of sys.argv[1:] which has unicode elements of the form u"key=value". If this is None (default), then self.argv will be used. - class : (list, tuple) of Configurables + classes : (list, tuple) of Configurables A sequence of Configurable classes that will be used to map shortnames to longnames. """ + from IPython.config.configurable import Configurable + self.clear() if argv is None: argv = self.argv if classes is None: classes = self.classes - # print argv - + # Create the mapping between shortnames and longnames. shortnames = {} for cls in classes: - sn = cls.class_get_shortnames() - # Check for duplicate shortnames and raise if found. - for k, v in sn.items(): - if k in shortnames: - raise KeyError( - "duplicate shortname: %s and %s both use the shortname: %s" %\ - (v, shortnames[k], k) - ) - shortnames.update(sn) - - # print shortnames + if issubclass(cls, Configurable): + sn = cls.class_get_shortnames() + # Check for duplicate shortnames and raise if found. + for k, v in sn.items(): + if k in shortnames: + raise KeyError( + 'Duplicate shortname: both %s and %s use the shortname: "%s"' %\ + (v, shortnames[k], k) + ) + shortnames.update(sn) for item in argv: pair = tuple(item.split("=")) @@ -393,8 +390,14 @@ class KeyValueConfigLoader(CommandLineConfigLoader): lhs = shortnames[lhs] exec_str = 'self.config.' + lhs + '=' + rhs try: + # Try to see if regular Python syntax will work. This + # won't handle strings as the quote marks are removed + # by the system shell. exec exec_str in locals(), globals() except (NameError, SyntaxError): + # This case happens if the rhs is a string but without + # the quote marks. We add the quote marks and see if + # it succeeds. If it still fails, we let it raise. exec_str = 'self.config.' + lhs + '="' + rhs + '"' exec exec_str in locals(), globals() return self.config diff --git a/IPython/config/tests/test_configurable.py b/IPython/config/tests/test_configurable.py index d57c36d..b4d541f 100644 --- a/IPython/config/tests/test_configurable.py +++ b/IPython/config/tests/test_configurable.py @@ -35,19 +35,26 @@ from IPython.config.loader import Config class MyConfigurable(Configurable): - a = Int(1, config=True) - b = Float(1.0, config=True) + a = Int(1, config=True, shortname="a", help="The integer a.") + b = Float(1.0, config=True, shortname="b", help="The integer b.") c = Str('no config') +mc_help=u"""MyConfigurable options +---------------------- +MyConfigurable.a : Int (shortname=a) + The integer a. +MyConfigurable.b : Float (shortname=b) + The integer b.""" + class Foo(Configurable): - a = Int(0, config=True) + a = Int(0, config=True, shortname="a", help="The integer a.") b = Str('nope', config=True) class Bar(Foo): - b = Str('gotit', config=False) - c = Float(config=True) + b = Str('gotit', config=False, shortname="b", help="The string b.") + c = Float(config=True, shortname="c", help="The string c.") class TestConfigurableConfig(TestCase): @@ -122,3 +129,15 @@ class TestConfigurableConfig(TestCase): self.assertEquals(c.a, 2) self.assertEquals(c.b, 'and') self.assertEquals(c.c, 20.0) + + def test_shortnames(self): + sn = MyConfigurable.class_get_shortnames() + self.assertEquals(sn, {'a': 'MyConfigurable.a', 'b': 'MyConfigurable.b'}) + sn = Foo.class_get_shortnames() + self.assertEquals(sn, {'a': 'Foo.a'}) + sn = Bar.class_get_shortnames() + self.assertEquals(sn, {'a': 'Bar.a', 'c': 'Bar.c'}) + + def test_help(self): + self.assertEquals(MyConfigurable.class_get_help(), mc_help) + diff --git a/IPython/config/tests/test_loader.py b/IPython/config/tests/test_loader.py index 5e41b73..3ec7b3c 100755 --- a/IPython/config/tests/test_loader.py +++ b/IPython/config/tests/test_loader.py @@ -24,6 +24,8 @@ import os from tempfile import mkstemp from unittest import TestCase +from IPython.utils.traitlets import Int, Unicode +from IPython.config.configurable import Configurable from IPython.config.loader import ( Config, PyFileConfigLoader, @@ -123,6 +125,24 @@ class TestKeyValueCL(TestCase): self.assertEquals(config.Foo.Bam.value, range(10)) self.assertEquals(config.D.C.value, 'hi there') + def test_shortname(self): + class Foo(Configurable): + i = Int(0, config=True, shortname="i") + s = Unicode('hi', config=True, shortname="s") + cl = KeyValueConfigLoader() + config = cl.load_config(["i=20", "s=there"], classes=[Foo]) + self.assertEquals(config.Foo.i, 20) + self.assertEquals(config.Foo.s, "there") + + def test_duplicate(self): + class Foo(Configurable): + i = Int(0, config=True, shortname="i") + class Bar(Configurable): + i = Int(0, config=True, shortname="i") + cl = KeyValueConfigLoader() + self.assertRaises(KeyError, cl.load_config, ["i=20", "s=there"], classes=[Foo, Bar]) + + class TestConfig(TestCase): def test_setget(self):