##// END OF EJS Templates
AttributeError no longer raised on missing config
MinRK -
Show More
@@ -1,282 +1,282 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """
2 """
3 Tests for IPython.config.loader
3 Tests for IPython.config.loader
4
4
5 Authors:
5 Authors:
6
6
7 * Brian Granger
7 * Brian Granger
8 * Fernando Perez (design help)
8 * Fernando Perez (design help)
9 """
9 """
10
10
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12 # Copyright (C) 2008-2011 The IPython Development Team
12 # Copyright (C) 2008 The IPython Development Team
13 #
13 #
14 # Distributed under the terms of the BSD License. The full license is in
14 # Distributed under the terms of the BSD License. The full license is in
15 # the file COPYING, distributed as part of this software.
15 # the file COPYING, distributed as part of this software.
16 #-----------------------------------------------------------------------------
16 #-----------------------------------------------------------------------------
17
17
18 #-----------------------------------------------------------------------------
18 #-----------------------------------------------------------------------------
19 # Imports
19 # Imports
20 #-----------------------------------------------------------------------------
20 #-----------------------------------------------------------------------------
21
21
22 import os
22 import os
23 import sys
23 import sys
24 from tempfile import mkstemp
24 from tempfile import mkstemp
25 from unittest import TestCase
25 from unittest import TestCase
26
26
27 from nose import SkipTest
27 from nose import SkipTest
28
28
29 from IPython.testing.tools import mute_warn
29 from IPython.testing.tools import mute_warn
30
30
31 from IPython.config.loader import (
31 from IPython.config.loader import (
32 Config,
32 Config,
33 PyFileConfigLoader,
33 PyFileConfigLoader,
34 KeyValueConfigLoader,
34 KeyValueConfigLoader,
35 ArgParseConfigLoader,
35 ArgParseConfigLoader,
36 KVArgParseConfigLoader,
36 KVArgParseConfigLoader,
37 ConfigError
37 ConfigError
38 )
38 )
39
39
40 #-----------------------------------------------------------------------------
40 #-----------------------------------------------------------------------------
41 # Actual tests
41 # Actual tests
42 #-----------------------------------------------------------------------------
42 #-----------------------------------------------------------------------------
43
43
44
44
45 pyfile = """
45 pyfile = """
46 c = get_config()
46 c = get_config()
47 c.a=10
47 c.a=10
48 c.b=20
48 c.b=20
49 c.Foo.Bar.value=10
49 c.Foo.Bar.value=10
50 c.Foo.Bam.value=list(range(10)) # list() is just so it's the same on Python 3
50 c.Foo.Bam.value=list(range(10)) # list() is just so it's the same on Python 3
51 c.D.C.value='hi there'
51 c.D.C.value='hi there'
52 """
52 """
53
53
54 class TestPyFileCL(TestCase):
54 class TestPyFileCL(TestCase):
55
55
56 def test_basic(self):
56 def test_basic(self):
57 fd, fname = mkstemp('.py')
57 fd, fname = mkstemp('.py')
58 f = os.fdopen(fd, 'w')
58 f = os.fdopen(fd, 'w')
59 f.write(pyfile)
59 f.write(pyfile)
60 f.close()
60 f.close()
61 # Unlink the file
61 # Unlink the file
62 cl = PyFileConfigLoader(fname)
62 cl = PyFileConfigLoader(fname)
63 config = cl.load_config()
63 config = cl.load_config()
64 self.assertEqual(config.a, 10)
64 self.assertEqual(config.a, 10)
65 self.assertEqual(config.b, 20)
65 self.assertEqual(config.b, 20)
66 self.assertEqual(config.Foo.Bar.value, 10)
66 self.assertEqual(config.Foo.Bar.value, 10)
67 self.assertEqual(config.Foo.Bam.value, range(10))
67 self.assertEqual(config.Foo.Bam.value, range(10))
68 self.assertEqual(config.D.C.value, 'hi there')
68 self.assertEqual(config.D.C.value, 'hi there')
69
69
70 class MyLoader1(ArgParseConfigLoader):
70 class MyLoader1(ArgParseConfigLoader):
71 def _add_arguments(self, aliases=None, flags=None):
71 def _add_arguments(self, aliases=None, flags=None):
72 p = self.parser
72 p = self.parser
73 p.add_argument('-f', '--foo', dest='Global.foo', type=str)
73 p.add_argument('-f', '--foo', dest='Global.foo', type=str)
74 p.add_argument('-b', dest='MyClass.bar', type=int)
74 p.add_argument('-b', dest='MyClass.bar', type=int)
75 p.add_argument('-n', dest='n', action='store_true')
75 p.add_argument('-n', dest='n', action='store_true')
76 p.add_argument('Global.bam', type=str)
76 p.add_argument('Global.bam', type=str)
77
77
78 class MyLoader2(ArgParseConfigLoader):
78 class MyLoader2(ArgParseConfigLoader):
79 def _add_arguments(self, aliases=None, flags=None):
79 def _add_arguments(self, aliases=None, flags=None):
80 subparsers = self.parser.add_subparsers(dest='subparser_name')
80 subparsers = self.parser.add_subparsers(dest='subparser_name')
81 subparser1 = subparsers.add_parser('1')
81 subparser1 = subparsers.add_parser('1')
82 subparser1.add_argument('-x',dest='Global.x')
82 subparser1.add_argument('-x',dest='Global.x')
83 subparser2 = subparsers.add_parser('2')
83 subparser2 = subparsers.add_parser('2')
84 subparser2.add_argument('y')
84 subparser2.add_argument('y')
85
85
86 class TestArgParseCL(TestCase):
86 class TestArgParseCL(TestCase):
87
87
88 def test_basic(self):
88 def test_basic(self):
89 cl = MyLoader1()
89 cl = MyLoader1()
90 config = cl.load_config('-f hi -b 10 -n wow'.split())
90 config = cl.load_config('-f hi -b 10 -n wow'.split())
91 self.assertEqual(config.Global.foo, 'hi')
91 self.assertEqual(config.Global.foo, 'hi')
92 self.assertEqual(config.MyClass.bar, 10)
92 self.assertEqual(config.MyClass.bar, 10)
93 self.assertEqual(config.n, True)
93 self.assertEqual(config.n, True)
94 self.assertEqual(config.Global.bam, 'wow')
94 self.assertEqual(config.Global.bam, 'wow')
95 config = cl.load_config(['wow'])
95 config = cl.load_config(['wow'])
96 self.assertEqual(config.keys(), ['Global'])
96 self.assertEqual(config.keys(), ['Global'])
97 self.assertEqual(config.Global.keys(), ['bam'])
97 self.assertEqual(config.Global.keys(), ['bam'])
98 self.assertEqual(config.Global.bam, 'wow')
98 self.assertEqual(config.Global.bam, 'wow')
99
99
100 def test_add_arguments(self):
100 def test_add_arguments(self):
101 cl = MyLoader2()
101 cl = MyLoader2()
102 config = cl.load_config('2 frobble'.split())
102 config = cl.load_config('2 frobble'.split())
103 self.assertEqual(config.subparser_name, '2')
103 self.assertEqual(config.subparser_name, '2')
104 self.assertEqual(config.y, 'frobble')
104 self.assertEqual(config.y, 'frobble')
105 config = cl.load_config('1 -x frobble'.split())
105 config = cl.load_config('1 -x frobble'.split())
106 self.assertEqual(config.subparser_name, '1')
106 self.assertEqual(config.subparser_name, '1')
107 self.assertEqual(config.Global.x, 'frobble')
107 self.assertEqual(config.Global.x, 'frobble')
108
108
109 def test_argv(self):
109 def test_argv(self):
110 cl = MyLoader1(argv='-f hi -b 10 -n wow'.split())
110 cl = MyLoader1(argv='-f hi -b 10 -n wow'.split())
111 config = cl.load_config()
111 config = cl.load_config()
112 self.assertEqual(config.Global.foo, 'hi')
112 self.assertEqual(config.Global.foo, 'hi')
113 self.assertEqual(config.MyClass.bar, 10)
113 self.assertEqual(config.MyClass.bar, 10)
114 self.assertEqual(config.n, True)
114 self.assertEqual(config.n, True)
115 self.assertEqual(config.Global.bam, 'wow')
115 self.assertEqual(config.Global.bam, 'wow')
116
116
117
117
118 class TestKeyValueCL(TestCase):
118 class TestKeyValueCL(TestCase):
119 klass = KeyValueConfigLoader
119 klass = KeyValueConfigLoader
120
120
121 def test_basic(self):
121 def test_basic(self):
122 cl = self.klass()
122 cl = self.klass()
123 argv = ['--'+s.strip('c.') for s in pyfile.split('\n')[2:-1]]
123 argv = ['--'+s.strip('c.') for s in pyfile.split('\n')[2:-1]]
124 with mute_warn():
124 with mute_warn():
125 config = cl.load_config(argv)
125 config = cl.load_config(argv)
126 self.assertEqual(config.a, 10)
126 self.assertEqual(config.a, 10)
127 self.assertEqual(config.b, 20)
127 self.assertEqual(config.b, 20)
128 self.assertEqual(config.Foo.Bar.value, 10)
128 self.assertEqual(config.Foo.Bar.value, 10)
129 self.assertEqual(config.Foo.Bam.value, range(10))
129 self.assertEqual(config.Foo.Bam.value, range(10))
130 self.assertEqual(config.D.C.value, 'hi there')
130 self.assertEqual(config.D.C.value, 'hi there')
131
131
132 def test_expanduser(self):
132 def test_expanduser(self):
133 cl = self.klass()
133 cl = self.klass()
134 argv = ['--a=~/1/2/3', '--b=~', '--c=~/', '--d="~/"']
134 argv = ['--a=~/1/2/3', '--b=~', '--c=~/', '--d="~/"']
135 with mute_warn():
135 with mute_warn():
136 config = cl.load_config(argv)
136 config = cl.load_config(argv)
137 self.assertEqual(config.a, os.path.expanduser('~/1/2/3'))
137 self.assertEqual(config.a, os.path.expanduser('~/1/2/3'))
138 self.assertEqual(config.b, os.path.expanduser('~'))
138 self.assertEqual(config.b, os.path.expanduser('~'))
139 self.assertEqual(config.c, os.path.expanduser('~/'))
139 self.assertEqual(config.c, os.path.expanduser('~/'))
140 self.assertEqual(config.d, '~/')
140 self.assertEqual(config.d, '~/')
141
141
142 def test_extra_args(self):
142 def test_extra_args(self):
143 cl = self.klass()
143 cl = self.klass()
144 with mute_warn():
144 with mute_warn():
145 config = cl.load_config(['--a=5', 'b', '--c=10', 'd'])
145 config = cl.load_config(['--a=5', 'b', '--c=10', 'd'])
146 self.assertEqual(cl.extra_args, ['b', 'd'])
146 self.assertEqual(cl.extra_args, ['b', 'd'])
147 self.assertEqual(config.a, 5)
147 self.assertEqual(config.a, 5)
148 self.assertEqual(config.c, 10)
148 self.assertEqual(config.c, 10)
149 with mute_warn():
149 with mute_warn():
150 config = cl.load_config(['--', '--a=5', '--c=10'])
150 config = cl.load_config(['--', '--a=5', '--c=10'])
151 self.assertEqual(cl.extra_args, ['--a=5', '--c=10'])
151 self.assertEqual(cl.extra_args, ['--a=5', '--c=10'])
152
152
153 def test_unicode_args(self):
153 def test_unicode_args(self):
154 cl = self.klass()
154 cl = self.klass()
155 argv = [u'--a=épsîlön']
155 argv = [u'--a=épsîlön']
156 with mute_warn():
156 with mute_warn():
157 config = cl.load_config(argv)
157 config = cl.load_config(argv)
158 self.assertEqual(config.a, u'épsîlön')
158 self.assertEqual(config.a, u'épsîlön')
159
159
160 def test_unicode_bytes_args(self):
160 def test_unicode_bytes_args(self):
161 uarg = u'--a=é'
161 uarg = u'--a=é'
162 try:
162 try:
163 barg = uarg.encode(sys.stdin.encoding)
163 barg = uarg.encode(sys.stdin.encoding)
164 except (TypeError, UnicodeEncodeError):
164 except (TypeError, UnicodeEncodeError):
165 raise SkipTest("sys.stdin.encoding can't handle 'é'")
165 raise SkipTest("sys.stdin.encoding can't handle 'é'")
166
166
167 cl = self.klass()
167 cl = self.klass()
168 with mute_warn():
168 with mute_warn():
169 config = cl.load_config([barg])
169 config = cl.load_config([barg])
170 self.assertEqual(config.a, u'é')
170 self.assertEqual(config.a, u'é')
171
171
172 def test_unicode_alias(self):
172 def test_unicode_alias(self):
173 cl = self.klass()
173 cl = self.klass()
174 argv = [u'--a=épsîlön']
174 argv = [u'--a=épsîlön']
175 with mute_warn():
175 with mute_warn():
176 config = cl.load_config(argv, aliases=dict(a='A.a'))
176 config = cl.load_config(argv, aliases=dict(a='A.a'))
177 self.assertEqual(config.A.a, u'épsîlön')
177 self.assertEqual(config.A.a, u'épsîlön')
178
178
179
179
180 class TestArgParseKVCL(TestKeyValueCL):
180 class TestArgParseKVCL(TestKeyValueCL):
181 klass = KVArgParseConfigLoader
181 klass = KVArgParseConfigLoader
182
182
183 def test_expanduser2(self):
183 def test_expanduser2(self):
184 cl = self.klass()
184 cl = self.klass()
185 argv = ['-a', '~/1/2/3', '--b', "'~/1/2/3'"]
185 argv = ['-a', '~/1/2/3', '--b', "'~/1/2/3'"]
186 with mute_warn():
186 with mute_warn():
187 config = cl.load_config(argv, aliases=dict(a='A.a', b='A.b'))
187 config = cl.load_config(argv, aliases=dict(a='A.a', b='A.b'))
188 self.assertEqual(config.A.a, os.path.expanduser('~/1/2/3'))
188 self.assertEqual(config.A.a, os.path.expanduser('~/1/2/3'))
189 self.assertEqual(config.A.b, '~/1/2/3')
189 self.assertEqual(config.A.b, '~/1/2/3')
190
190
191 def test_eval(self):
191 def test_eval(self):
192 cl = self.klass()
192 cl = self.klass()
193 argv = ['-c', 'a=5']
193 argv = ['-c', 'a=5']
194 with mute_warn():
194 with mute_warn():
195 config = cl.load_config(argv, aliases=dict(c='A.c'))
195 config = cl.load_config(argv, aliases=dict(c='A.c'))
196 self.assertEqual(config.A.c, u"a=5")
196 self.assertEqual(config.A.c, u"a=5")
197
197
198
198
199 class TestConfig(TestCase):
199 class TestConfig(TestCase):
200
200
201 def test_setget(self):
201 def test_setget(self):
202 c = Config()
202 c = Config()
203 c.a = 10
203 c.a = 10
204 self.assertEqual(c.a, 10)
204 self.assertEqual(c.a, 10)
205 self.assertEqual('b' in c, False)
205 self.assertEqual('b' in c, False)
206
206
207 def test_auto_section(self):
207 def test_auto_section(self):
208 c = Config()
208 c = Config()
209 self.assertEqual('A' in c, True)
209 self.assertEqual('A' in c, True)
210 self.assertEqual(c._has_section('A'), False)
210 self.assertEqual(c._has_section('A'), False)
211 A = c.A
211 A = c.A
212 A.foo = 'hi there'
212 A.foo = 'hi there'
213 self.assertEqual(c._has_section('A'), True)
213 self.assertEqual(c._has_section('A'), True)
214 self.assertEqual(c.A.foo, 'hi there')
214 self.assertEqual(c.A.foo, 'hi there')
215 del c.A
215 del c.A
216 self.assertEqual(len(c.A.keys()),0)
216 self.assertEqual(len(c.A.keys()),0)
217
217
218 def test_merge_doesnt_exist(self):
218 def test_merge_doesnt_exist(self):
219 c1 = Config()
219 c1 = Config()
220 c2 = Config()
220 c2 = Config()
221 c2.bar = 10
221 c2.bar = 10
222 c2.Foo.bar = 10
222 c2.Foo.bar = 10
223 c1.merge(c2)
223 c1.merge(c2)
224 self.assertEqual(c1.Foo.bar, 10)
224 self.assertEqual(c1.Foo.bar, 10)
225 self.assertEqual(c1.bar, 10)
225 self.assertEqual(c1.bar, 10)
226 c2.Bar.bar = 10
226 c2.Bar.bar = 10
227 c1.merge(c2)
227 c1.merge(c2)
228 self.assertEqual(c1.Bar.bar, 10)
228 self.assertEqual(c1.Bar.bar, 10)
229
229
230 def test_merge_exists(self):
230 def test_merge_exists(self):
231 c1 = Config()
231 c1 = Config()
232 c2 = Config()
232 c2 = Config()
233 c1.Foo.bar = 10
233 c1.Foo.bar = 10
234 c1.Foo.bam = 30
234 c1.Foo.bam = 30
235 c2.Foo.bar = 20
235 c2.Foo.bar = 20
236 c2.Foo.wow = 40
236 c2.Foo.wow = 40
237 c1.merge(c2)
237 c1.merge(c2)
238 self.assertEqual(c1.Foo.bam, 30)
238 self.assertEqual(c1.Foo.bam, 30)
239 self.assertEqual(c1.Foo.bar, 20)
239 self.assertEqual(c1.Foo.bar, 20)
240 self.assertEqual(c1.Foo.wow, 40)
240 self.assertEqual(c1.Foo.wow, 40)
241 c2.Foo.Bam.bam = 10
241 c2.Foo.Bam.bam = 10
242 c1.merge(c2)
242 c1.merge(c2)
243 self.assertEqual(c1.Foo.Bam.bam, 10)
243 self.assertEqual(c1.Foo.Bam.bam, 10)
244
244
245 def test_deepcopy(self):
245 def test_deepcopy(self):
246 c1 = Config()
246 c1 = Config()
247 c1.Foo.bar = 10
247 c1.Foo.bar = 10
248 c1.Foo.bam = 30
248 c1.Foo.bam = 30
249 c1.a = 'asdf'
249 c1.a = 'asdf'
250 c1.b = range(10)
250 c1.b = range(10)
251 import copy
251 import copy
252 c2 = copy.deepcopy(c1)
252 c2 = copy.deepcopy(c1)
253 self.assertEqual(c1, c2)
253 self.assertEqual(c1, c2)
254 self.assertTrue(c1 is not c2)
254 self.assertTrue(c1 is not c2)
255 self.assertTrue(c1.Foo is not c2.Foo)
255 self.assertTrue(c1.Foo is not c2.Foo)
256
256
257 def test_builtin(self):
257 def test_builtin(self):
258 c1 = Config()
258 c1 = Config()
259 exec 'foo = True' in c1
259 exec 'foo = True' in c1
260 self.assertEqual(c1.foo, True)
260 self.assertEqual(c1.foo, True)
261 c1.format = "json"
261 c1.format = "json"
262
262
263 def test_fromdict(self):
263 def test_fromdict(self):
264 c1 = Config({'Foo' : {'bar' : 1}})
264 c1 = Config({'Foo' : {'bar' : 1}})
265 self.assertEqual(c1.Foo.__class__, Config)
265 self.assertEqual(c1.Foo.__class__, Config)
266 self.assertEqual(c1.Foo.bar, 1)
266 self.assertEqual(c1.Foo.bar, 1)
267
267
268 def test_fromdictmerge(self):
268 def test_fromdictmerge(self):
269 c1 = Config()
269 c1 = Config()
270 c2 = Config({'Foo' : {'bar' : 1}})
270 c2 = Config({'Foo' : {'bar' : 1}})
271 c1.merge(c2)
271 c1.merge(c2)
272 self.assertEqual(c1.Foo.__class__, Config)
272 self.assertEqual(c1.Foo.__class__, Config)
273 self.assertEqual(c1.Foo.bar, 1)
273 self.assertEqual(c1.Foo.bar, 1)
274
274
275 def test_fromdictmerge2(self):
275 def test_fromdictmerge2(self):
276 c1 = Config({'Foo' : {'baz' : 2}})
276 c1 = Config({'Foo' : {'baz' : 2}})
277 c2 = Config({'Foo' : {'bar' : 1}})
277 c2 = Config({'Foo' : {'bar' : 1}})
278 c1.merge(c2)
278 c1.merge(c2)
279 self.assertEqual(c1.Foo.__class__, Config)
279 self.assertEqual(c1.Foo.__class__, Config)
280 self.assertEqual(c1.Foo.bar, 1)
280 self.assertEqual(c1.Foo.bar, 1)
281 self.assertEqual(c1.Foo.baz, 2)
281 self.assertEqual(c1.Foo.baz, 2)
282 self.assertRaises(AttributeError, getattr, c2.Foo, 'baz')
282 self.assertNotIn('baz', c2.Foo)
General Comments 0
You need to be logged in to leave comments. Login now