##// END OF EJS Templates
add parent to Configurable...
add parent to Configurable this adds the notion of a parent and member config, so the config: c.Foo.Bar.attr = value will only set `Bar.attr = value` for `Bar` instances which are members of `Foo` instances. The mechanism for doing this is ```python f = Foo(config=cfg) f.b = Bar(parent=f) ``` This Instance config has higher priority than plain class config for Bar, but still lower priority than direct keyword arg trait assignment. The main implication this has is to change the standard creation of descendants: ```python self.bar = Bar(config=self.config) ``` into a direct parent expression ```python self.bar = Bar(parent=self) ``` This also means that most Configurables will actually have a handle on their parent object.

File last commit:

r10873:0e05c0ad
r11062:7f44a560
Show More
test_loader.py
284 lines | 8.9 KiB | text/x-python | PythonLexer
Brian Granger
Work on Application and loader testing.
r2187 # encoding: utf-8
"""
Tests for IPython.config.loader
Authors:
* Brian Granger
* Fernando Perez (design help)
"""
#-----------------------------------------------------------------------------
Matthias BUSSONNIER
update copyright to 2011/20xx-2011...
r5390 # Copyright (C) 2008-2011 The IPython Development Team
Brian Granger
Work on Application and loader testing.
r2187 #
# Distributed under the terms of the BSD License. The full license is in
# the file COPYING, distributed as part of this software.
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
# Imports
#-----------------------------------------------------------------------------
import os
MinRK
fix handling of unicode in KV loader...
r4162 import sys
Brian Granger
Work on Application and loader testing.
r2187 from tempfile import mkstemp
from unittest import TestCase
MinRK
fix handling of unicode in KV loader...
r4162 from nose import SkipTest
MinRK
aliases match flag pattern ('-' as wordsep, not '_')...
r4214 from IPython.testing.tools import mute_warn
MinRK
add Integer traitlet...
r5344 from IPython.utils.traitlets import Unicode
Brian Granger
Added new tests for config.loader and configurable.
r3791 from IPython.config.configurable import Configurable
Brian Granger
Massive refactoring of of the core....
r2245 from IPython.config.loader import (
Config,
Brian Granger
Added KeyValueConfigLoader with tests.
r3786 PyFileConfigLoader,
KeyValueConfigLoader,
Brian Granger
Massive refactoring of of the core....
r2245 ArgParseConfigLoader,
MinRK
fix type=str->unicode in argparse kv loader...
r4830 KVArgParseConfigLoader,
Brian Granger
Massive refactoring of of the core....
r2245 ConfigError
)
Brian Granger
Work on Application and loader testing.
r2187
#-----------------------------------------------------------------------------
# Actual tests
#-----------------------------------------------------------------------------
pyfile = """
Fernando Perez
Fix failing config test: https://bugs.launchpad.net/ipython/+bug/503731...
r2394 c = get_config()
Brian Granger
Added KeyValueConfigLoader with tests.
r3786 c.a=10
c.b=20
c.Foo.Bar.value=10
Thomas Kluyver
Fix config loader test for Python 3.
r4762 c.Foo.Bam.value=list(range(10)) # list() is just so it's the same on Python 3
Brian Granger
Added KeyValueConfigLoader with tests.
r3786 c.D.C.value='hi there'
Brian Granger
Work on Application and loader testing.
r2187 """
class TestPyFileCL(TestCase):
def test_basic(self):
Fernando Perez
Progress towards getting the test suite in shape again....
r2392 fd, fname = mkstemp('.py')
Brian Granger
Work on Application and loader testing.
r2187 f = os.fdopen(fd, 'w')
f.write(pyfile)
f.close()
Brian Granger
Minor changes to a few files to reflect design discussion.
r2198 # Unlink the file
Brian Granger
Work on Application and loader testing.
r2187 cl = PyFileConfigLoader(fname)
config = cl.load_config()
Bradley M. Froehle
s/assertEquals/assertEqual/
r7874 self.assertEqual(config.a, 10)
self.assertEqual(config.b, 20)
self.assertEqual(config.Foo.Bar.value, 10)
self.assertEqual(config.Foo.Bam.value, range(10))
self.assertEqual(config.D.C.value, 'hi there')
Brian Granger
Work on Application and loader testing.
r2187
Brian Granger
Refactored the command line config system and other aspects of config....
r2501 class MyLoader1(ArgParseConfigLoader):
MinRK
use cfg._merge instead of update in loader...
r4606 def _add_arguments(self, aliases=None, flags=None):
Brian Granger
Refactored the command line config system and other aspects of config....
r2501 p = self.parser
p.add_argument('-f', '--foo', dest='Global.foo', type=str)
p.add_argument('-b', dest='MyClass.bar', type=int)
p.add_argument('-n', dest='n', action='store_true')
p.add_argument('Global.bam', type=str)
class MyLoader2(ArgParseConfigLoader):
MinRK
use cfg._merge instead of update in loader...
r4606 def _add_arguments(self, aliases=None, flags=None):
Brian Granger
Refactored the command line config system and other aspects of config....
r2501 subparsers = self.parser.add_subparsers(dest='subparser_name')
subparser1 = subparsers.add_parser('1')
subparser1.add_argument('-x',dest='Global.x')
subparser2 = subparsers.add_parser('2')
subparser2.add_argument('y')
Brian Granger
Work on the config system....
r2500
Brian Granger
Work on Application and loader testing.
r2187 class TestArgParseCL(TestCase):
def test_basic(self):
Brian Granger
Refactored the command line config system and other aspects of config....
r2501 cl = MyLoader1()
Brian Granger
Work on Application and loader testing.
r2187 config = cl.load_config('-f hi -b 10 -n wow'.split())
Bradley M. Froehle
s/assertEquals/assertEqual/
r7874 self.assertEqual(config.Global.foo, 'hi')
self.assertEqual(config.MyClass.bar, 10)
self.assertEqual(config.n, True)
self.assertEqual(config.Global.bam, 'wow')
Brian Granger
Work on the config system....
r2500 config = cl.load_config(['wow'])
Bradley M. Froehle
s/assertEquals/assertEqual/
r7874 self.assertEqual(config.keys(), ['Global'])
self.assertEqual(config.Global.keys(), ['bam'])
self.assertEqual(config.Global.bam, 'wow')
Brian Granger
Work on Application and loader testing.
r2187
def test_add_arguments(self):
Brian Granger
Refactored the command line config system and other aspects of config....
r2501 cl = MyLoader2()
Brian Granger
Work on Application and loader testing.
r2187 config = cl.load_config('2 frobble'.split())
Bradley M. Froehle
s/assertEquals/assertEqual/
r7874 self.assertEqual(config.subparser_name, '2')
self.assertEqual(config.y, 'frobble')
Brian Granger
Work on Application and loader testing.
r2187 config = cl.load_config('1 -x frobble'.split())
Bradley M. Froehle
s/assertEquals/assertEqual/
r7874 self.assertEqual(config.subparser_name, '1')
self.assertEqual(config.Global.x, 'frobble')
Brian Granger
Massive refactoring of of the core....
r2245
Brian Granger
Work on the config system....
r2500 def test_argv(self):
Brian Granger
Refactored the command line config system and other aspects of config....
r2501 cl = MyLoader1(argv='-f hi -b 10 -n wow'.split())
Brian Granger
Work on the config system....
r2500 config = cl.load_config()
Bradley M. Froehle
s/assertEquals/assertEqual/
r7874 self.assertEqual(config.Global.foo, 'hi')
self.assertEqual(config.MyClass.bar, 10)
self.assertEqual(config.n, True)
self.assertEqual(config.Global.bam, 'wow')
Brian Granger
Work on the config system....
r2500
Brian Granger
Added KeyValueConfigLoader with tests.
r3786 class TestKeyValueCL(TestCase):
MinRK
fix type=str->unicode in argparse kv loader...
r4830 klass = KeyValueConfigLoader
Brian Granger
Added KeyValueConfigLoader with tests.
r3786
def test_basic(self):
MinRK
fix type=str->unicode in argparse kv loader...
r4830 cl = self.klass()
MinRK
disallow no-prefix `ipython foo=bar` argument style....
r4197 argv = ['--'+s.strip('c.') for s in pyfile.split('\n')[2:-1]]
MinRK
aliases match flag pattern ('-' as wordsep, not '_')...
r4214 with mute_warn():
config = cl.load_config(argv)
Bradley M. Froehle
s/assertEquals/assertEqual/
r7874 self.assertEqual(config.a, 10)
self.assertEqual(config.b, 20)
self.assertEqual(config.Foo.Bar.value, 10)
self.assertEqual(config.Foo.Bam.value, range(10))
self.assertEqual(config.D.C.value, 'hi there')
MinRK
allow extra_args in applications
r3958
MinRK
expand '~' with path.expanduser in KVLoader...
r5189 def test_expanduser(self):
cl = self.klass()
argv = ['--a=~/1/2/3', '--b=~', '--c=~/', '--d="~/"']
with mute_warn():
config = cl.load_config(argv)
Bradley M. Froehle
s/assertEquals/assertEqual/
r7874 self.assertEqual(config.a, os.path.expanduser('~/1/2/3'))
self.assertEqual(config.b, os.path.expanduser('~'))
self.assertEqual(config.c, os.path.expanduser('~/'))
self.assertEqual(config.d, '~/')
MinRK
expand '~' with path.expanduser in KVLoader...
r5189
MinRK
allow extra_args in applications
r3958 def test_extra_args(self):
MinRK
fix type=str->unicode in argparse kv loader...
r4830 cl = self.klass()
MinRK
aliases match flag pattern ('-' as wordsep, not '_')...
r4214 with mute_warn():
config = cl.load_config(['--a=5', 'b', '--c=10', 'd'])
Bradley M. Froehle
s/assertEquals/assertEqual/
r7874 self.assertEqual(cl.extra_args, ['b', 'd'])
self.assertEqual(config.a, 5)
self.assertEqual(config.c, 10)
MinRK
aliases match flag pattern ('-' as wordsep, not '_')...
r4214 with mute_warn():
config = cl.load_config(['--', '--a=5', '--c=10'])
Bradley M. Froehle
s/assertEquals/assertEqual/
r7874 self.assertEqual(cl.extra_args, ['--a=5', '--c=10'])
MinRK
fix handling of unicode in KV loader...
r4162
def test_unicode_args(self):
MinRK
fix type=str->unicode in argparse kv loader...
r4830 cl = self.klass()
MinRK
disallow no-prefix `ipython foo=bar` argument style....
r4197 argv = [u'--a=épsîlön']
MinRK
aliases match flag pattern ('-' as wordsep, not '_')...
r4214 with mute_warn():
config = cl.load_config(argv)
Bradley M. Froehle
s/assertEquals/assertEqual/
r7874 self.assertEqual(config.a, u'épsîlön')
MinRK
fix handling of unicode in KV loader...
r4162
def test_unicode_bytes_args(self):
MinRK
disallow no-prefix `ipython foo=bar` argument style....
r4197 uarg = u'--a=é'
MinRK
fix handling of unicode in KV loader...
r4162 try:
barg = uarg.encode(sys.stdin.encoding)
except (TypeError, UnicodeEncodeError):
raise SkipTest("sys.stdin.encoding can't handle 'é'")
MinRK
fix type=str->unicode in argparse kv loader...
r4830 cl = self.klass()
MinRK
aliases match flag pattern ('-' as wordsep, not '_')...
r4214 with mute_warn():
config = cl.load_config([barg])
Bradley M. Froehle
s/assertEquals/assertEqual/
r7874 self.assertEqual(config.a, u'é')
MinRK
fix type=str->unicode in argparse kv loader...
r4830
def test_unicode_alias(self):
cl = self.klass()
argv = [u'--a=épsîlön']
with mute_warn():
config = cl.load_config(argv, aliases=dict(a='A.a'))
Bradley M. Froehle
s/assertEquals/assertEqual/
r7874 self.assertEqual(config.A.a, u'épsîlön')
MinRK
fix type=str->unicode in argparse kv loader...
r4830
Brian Granger
Added KeyValueConfigLoader with tests.
r3786
MinRK
fix type=str->unicode in argparse kv loader...
r4830 class TestArgParseKVCL(TestKeyValueCL):
klass = KVArgParseConfigLoader
Brian Granger
Added new tests for config.loader and configurable.
r3791
MinRK
expand '~' with path.expanduser in KVLoader...
r5189 def test_expanduser2(self):
cl = self.klass()
argv = ['-a', '~/1/2/3', '--b', "'~/1/2/3'"]
with mute_warn():
config = cl.load_config(argv, aliases=dict(a='A.a', b='A.b'))
Bradley M. Froehle
s/assertEquals/assertEqual/
r7874 self.assertEqual(config.A.a, os.path.expanduser('~/1/2/3'))
self.assertEqual(config.A.b, '~/1/2/3')
MinRK
expand '~' with path.expanduser in KVLoader...
r5189
MinRK
use eval for command-line args instead of exec...
r6757 def test_eval(self):
cl = self.klass()
argv = ['-c', 'a=5']
with mute_warn():
config = cl.load_config(argv, aliases=dict(c='A.c'))
Bradley M. Froehle
s/assertEquals/assertEqual/
r7874 self.assertEqual(config.A.c, u"a=5")
MinRK
use eval for command-line args instead of exec...
r6757
Brian Granger
Massive refactoring of of the core....
r2245 class TestConfig(TestCase):
def test_setget(self):
c = Config()
c.a = 10
Bradley M. Froehle
s/assertEquals/assertEqual/
r7874 self.assertEqual(c.a, 10)
self.assertEqual('b' in c, False)
Brian Granger
Massive refactoring of of the core....
r2245
def test_auto_section(self):
c = Config()
Bradley M. Froehle
s/assertEquals/assertEqual/
r7874 self.assertEqual('A' in c, True)
self.assertEqual(c._has_section('A'), False)
Brian Granger
Massive refactoring of of the core....
r2245 A = c.A
A.foo = 'hi there'
Bradley M. Froehle
s/assertEquals/assertEqual/
r7874 self.assertEqual(c._has_section('A'), True)
self.assertEqual(c.A.foo, 'hi there')
Brian Granger
Massive refactoring of of the core....
r2245 del c.A
Bradley M. Froehle
s/assertEquals/assertEqual/
r7874 self.assertEqual(len(c.A.keys()),0)
Brian Granger
Massive refactoring of of the core....
r2245
def test_merge_doesnt_exist(self):
c1 = Config()
c2 = Config()
c2.bar = 10
c2.Foo.bar = 10
MinRK
make Config.merge a public method...
r10873 c1.merge(c2)
Bradley M. Froehle
s/assertEquals/assertEqual/
r7874 self.assertEqual(c1.Foo.bar, 10)
self.assertEqual(c1.bar, 10)
Brian Granger
Massive refactoring of of the core....
r2245 c2.Bar.bar = 10
MinRK
make Config.merge a public method...
r10873 c1.merge(c2)
Bradley M. Froehle
s/assertEquals/assertEqual/
r7874 self.assertEqual(c1.Bar.bar, 10)
Brian Granger
Massive refactoring of of the core....
r2245
def test_merge_exists(self):
c1 = Config()
c2 = Config()
c1.Foo.bar = 10
c1.Foo.bam = 30
c2.Foo.bar = 20
c2.Foo.wow = 40
MinRK
make Config.merge a public method...
r10873 c1.merge(c2)
Bradley M. Froehle
s/assertEquals/assertEqual/
r7874 self.assertEqual(c1.Foo.bam, 30)
self.assertEqual(c1.Foo.bar, 20)
self.assertEqual(c1.Foo.wow, 40)
Brian Granger
Massive refactoring of of the core....
r2245 c2.Foo.Bam.bam = 10
MinRK
make Config.merge a public method...
r10873 c1.merge(c2)
Bradley M. Froehle
s/assertEquals/assertEqual/
r7874 self.assertEqual(c1.Foo.Bam.bam, 10)
Brian Granger
Massive refactoring of of the core....
r2245
def test_deepcopy(self):
c1 = Config()
c1.Foo.bar = 10
c1.Foo.bam = 30
c1.a = 'asdf'
c1.b = range(10)
import copy
c2 = copy.deepcopy(c1)
Bradley M. Froehle
s/assertEquals/assertEqual/
r7874 self.assertEqual(c1, c2)
Bradley M. Froehle
s/assert_/assertTrue/
r7876 self.assertTrue(c1 is not c2)
self.assertTrue(c1.Foo is not c2.Foo)
Brian Granger
Massive refactoring of of the core....
r2245
def test_builtin(self):
c1 = Config()
exec 'foo = True' in c1
Bradley M. Froehle
s/assertEquals/assertEqual/
r7874 self.assertEqual(c1.foo, True)
Brian Granger
Massive refactoring of of the core....
r2245 self.assertRaises(ConfigError, setattr, c1, 'ValueError', 10)
MinRK
test Config objects from dicts
r10870
def test_fromdict(self):
c1 = Config({'Foo' : {'bar' : 1}})
self.assertEqual(c1.Foo.__class__, Config)
self.assertEqual(c1.Foo.bar, 1)
MinRK
make Config.merge a public method...
r10873 def test_fromdictmerge(self):
MinRK
test Config objects from dicts
r10870 c1 = Config()
c2 = Config({'Foo' : {'bar' : 1}})
MinRK
make Config.merge a public method...
r10873 c1.merge(c2)
MinRK
test Config objects from dicts
r10870 self.assertEqual(c1.Foo.__class__, Config)
self.assertEqual(c1.Foo.bar, 1)
MinRK
make Config.merge a public method...
r10873 def test_fromdictmerge2(self):
MinRK
test Config objects from dicts
r10870 c1 = Config({'Foo' : {'baz' : 2}})
c2 = Config({'Foo' : {'bar' : 1}})
MinRK
make Config.merge a public method...
r10873 c1.merge(c2)
MinRK
test Config objects from dicts
r10870 self.assertEqual(c1.Foo.__class__, Config)
self.assertEqual(c1.Foo.bar, 1)
self.assertEqual(c1.Foo.baz, 2)
self.assertRaises(AttributeError, getattr, c2.Foo, 'baz')