##// END OF EJS Templates
Adding more documentation to config.application related files.
Brian Granger -
Show More
@@ -0,0 +1,90 b''
1 """
2 Tests for IPython.config.application.Application
3
4 Authors:
5
6 * Brian Granger
7 """
8
9 #-----------------------------------------------------------------------------
10 # Copyright (C) 2008-2011 The IPython Development Team
11 #
12 # Distributed under the terms of the BSD License. The full license is in
13 # the file COPYING, distributed as part of this software.
14 #-----------------------------------------------------------------------------
15
16 #-----------------------------------------------------------------------------
17 # Imports
18 #-----------------------------------------------------------------------------
19
20 from unittest import TestCase
21
22 from IPython.config.configurable import Configurable
23
24 from IPython.config.application import (
25 Application
26 )
27
28 from IPython.utils.traitlets import (
29 Bool, Unicode, Int, Float, List
30 )
31
32 #-----------------------------------------------------------------------------
33 # Code
34 #-----------------------------------------------------------------------------
35
36 class Foo(Configurable):
37
38 i = Int(0, config=True, shortname='i', help="The integer i.")
39 j = Int(1, config=True, shortname='j', help="The integer j.")
40 name = Unicode(u'Brian', config=True, shortname='name', help="First name.")
41
42
43 class Bar(Configurable):
44
45 enabled = Bool(True, config=True, shortname="enabled", help="Enable bar.")
46
47
48 class MyApp(Application):
49
50 app_name = Unicode(u'myapp')
51 running = Bool(False, config=True, shortname="running",
52 help="Is the app running?")
53 classes = List([Bar, Foo])
54 config_file = Unicode(u'', config=True, shortname="config_file",
55 help="Load this config file")
56
57 def init_foo(self):
58 self.foo = Foo(config=self.config)
59
60 def init_bar(self):
61 self.bar = Bar(config=self.config)
62
63
64 class TestApplication(TestCase):
65
66 def test_basic(self):
67 app = MyApp()
68 self.assertEquals(app.app_name, u'myapp')
69 self.assertEquals(app.running, False)
70 self.assertEquals(app.classes, [MyApp,Bar,Foo])
71 self.assertEquals(app.config_file, u'')
72
73 def test_config(self):
74 app = MyApp()
75 app.parse_command_line(["i=10","Foo.j=10","enabled=False","log_level=0"])
76 config = app.config
77 self.assertEquals(config.Foo.i, 10)
78 self.assertEquals(config.Foo.j, 10)
79 self.assertEquals(config.Bar.enabled, False)
80 self.assertEquals(config.MyApp.log_level,0)
81
82 def test_config_propagation(self):
83 app = MyApp()
84 app.parse_command_line(["i=10","Foo.j=10","enabled=False","log_level=0"])
85 app.init_foo()
86 app.init_bar()
87 self.assertEquals(app.foo.i, 10)
88 self.assertEquals(app.foo.j, 10)
89 self.assertEquals(app.bar.enabled, False)
90
@@ -1,132 +1,134 b''
1 1 # encoding: utf-8
2 2 """
3 3 A base class for a configurable application.
4 4
5 5 Authors:
6 6
7 7 * Brian Granger
8 8 """
9 9
10 10 #-----------------------------------------------------------------------------
11 11 # Copyright (C) 2008-2011 The IPython Development Team
12 12 #
13 13 # Distributed under the terms of the BSD License. The full license is in
14 14 # the file COPYING, distributed as part of this software.
15 15 #-----------------------------------------------------------------------------
16 16
17 17 #-----------------------------------------------------------------------------
18 18 # Imports
19 19 #-----------------------------------------------------------------------------
20 20
21 21 from copy import deepcopy
22 22 import logging
23 23 import sys
24 24
25 25 from IPython.config.configurable import SingletonConfigurable
26 26 from IPython.utils.traitlets import (
27 27 Unicode, List, Int, Enum
28 28 )
29 29 from IPython.config.loader import (
30 30 KeyValueConfigLoader, PyFileConfigLoader
31 31 )
32 32
33 33 #-----------------------------------------------------------------------------
34 34 # Application class
35 35 #-----------------------------------------------------------------------------
36 36
37 37
38 38 class Application(SingletonConfigurable):
39 """A singleton application with full configuration support."""
39 40
40 41 # The name of the application, will usually match the name of the command
41 42 # line application
42 43 app_name = Unicode(u'application')
43 44
44 45 # The description of the application that is printed at the beginning
45 46 # of the help.
46 47 description = Unicode(u'This is an application.')
47 48
48 49 # A sequence of Configurable subclasses whose config=True attributes will
49 50 # be exposed at the command line (shortnames and help).
50 51 classes = List([])
51 52
52 53 # The version string of this application.
53 54 version = Unicode(u'0.0')
54 55
55 56 # The log level for the application
56 57 log_level = Enum((0,10,20,30,40,50), default_value=logging.WARN,
57 58 config=True, shortname="log_level",
58 59 help="Set the log level (0,10,20,30,40,50).")
59 60
60 61 def __init__(self, **kwargs):
61 62 SingletonConfigurable.__init__(self, **kwargs)
62 63 # Add my class to self.classes so my attributes appear in command line
63 64 # options.
64 65 self.classes.insert(0, self.__class__)
65 66 self.init_logging()
66 67
67 68 def init_logging(self):
68 69 """Start logging for this application.
69 70
70 71 The default is to log to stdout using a StreaHandler. The log level
71 72 starts at loggin.WARN, but this can be adjusted by setting the
72 73 ``log_level`` attribute.
73 74 """
74 75 self.log = logging.getLogger(self.__class__.__name__)
75 76 self.log.setLevel(self.log_level)
76 77 self._log_handler = logging.StreamHandler()
77 78 self._log_formatter = logging.Formatter("[%(name)s] %(message)s")
78 79 self._log_handler.setFormatter(self._log_formatter)
79 80 self.log.addHandler(self._log_handler)
80 81
81 82 def _log_level_changed(self, name, old, new):
82 83 """Adjust the log level when log_level is set."""
83 84 self.log.setLevel(new)
84 85
85 86 def print_help(self):
86 87 """Print the help for each Configurable class in self.classes."""
87 88 for cls in self.classes:
88 89 cls.class_print_help()
89 90 print
90 91
91 92 def print_description(self):
92 93 """Print the application description."""
93 94 print self.description
94 95 print
95 96
96 97 def print_version(self):
97 98 """Print the version string."""
98 99 print self.version
99 100
100 101 def update_config(self, config):
102 """Fire the traits events when the config is updated."""
101 103 # Save a copy of the current config.
102 104 newconfig = deepcopy(self.config)
103 105 # Merge the new config into the current one.
104 106 newconfig._merge(config)
105 107 # Save the combined config as self.config, which triggers the traits
106 108 # events.
107 109 self.config = config
108 110
109 111 def parse_command_line(self, argv=None):
110 112 """Parse the command line arguments."""
111 113 argv = sys.argv[1:] if argv is None else argv
112 114
113 115 if '-h' in argv or '--h' in argv:
114 116 self.print_description()
115 117 self.print_help()
116 118 sys.exit(1)
117 119
118 120 if '--version' in argv:
119 121 self.print_version()
120 122 sys.exit(1)
121 123
122 124 loader = KeyValueConfigLoader(argv=argv, classes=self.classes)
123 125 config = loader.load_config()
124 126 self.update_config(config)
125 127
126 128 def load_config_file(self, filename, path=None):
127 129 """Load a .py based config file by filename and path."""
128 130 # TODO: this raises IOError if filename does not exist.
129 131 loader = PyFileConfigLoader(filename, path=path)
130 132 config = loader.load_config()
131 133 self.update_config(config)
132 134
@@ -1,61 +1,88 b''
1 1 """A simple example of how to use IPython.config.application.Application.
2 2
3 3 This should serve as a simple example that shows how the IPython config
4 4 system works. The main classes are:
5 5
6 6 * IPython.config.configurable.Configurable
7 7 * IPython.config.configurable.SingletonConfigurable
8 8 * IPython.config.loader.Config
9 9 * IPython.config.application.Application
10
11 To see the command line option help, run this program from the command line::
12
13 $ python appconfig.py -h
14
15 To make one of your classes configurable (from the command line and config
16 files) inherit from Configurable and declare class attributes as traits (see
17 classes Foo and Bar below). To make the traits configurable, you will need
18 to set the following options:
19
20 * ``config``: set to ``True`` to make the attribute configurable.
21 * ``shortname``: by default, configurable attributes are set using the syntax
22 "Classname.attributename". At the command line, this is a bit verbose, so
23 we allow "shortnames" to be declared. Setting a shortname is optional, but
24 when you do this, you can set the option at the command line using the
25 syntax: "shortname=value".
26 * ``help``: set the help string to display a help message when the ``-h``
27 option is given at the command line. The help string should be valid ReST.
28
29 When the config attribute of an Application is updated, it will fire all of
30 the trait's events for all of the config=True attributes.
10 31 """
11 32
12 33 import sys
13 34
14 35 from IPython.config.configurable import Configurable
15 36 from IPython.config.application import Application
16 37 from IPython.utils.traitlets import (
17 38 Bool, Unicode, Int, Float, List
18 39 )
19 40
41
20 42 class Foo(Configurable):
43 """A class that has configurable, typed attributes.
44
45 """
21 46
22 47 i = Int(0, config=True, shortname='i', help="The integer i.")
23 48 j = Int(1, config=True, shortname='j', help="The integer j.")
24 49 name = Unicode(u'Brian', config=True, shortname='name', help="First name.")
25 50
26 51
27 52 class Bar(Configurable):
28 53
29 54 enabled = Bool(True, config=True, shortname="enabled", help="Enable bar.")
30 55
31 56
32 57 class MyApp(Application):
33 58
34 59 app_name = Unicode(u'myapp')
35 60 running = Bool(False, config=True, shortname="running",
36 61 help="Is the app running?")
37 62 classes = List([Bar, Foo])
38 63 config_file = Unicode(u'', config=True, shortname="config_file",
39 64 help="Load this config file")
40 65
41 66 def init_foo(self):
67 # Pass config to other classes for them to inherit the config.
42 68 self.foo = Foo(config=self.config)
43 69
44 70 def init_bar(self):
71 # Pass config to other classes for them to inherit the config.
45 72 self.bar = Bar(config=self.config)
46 73
47 74
48 75
49 76 def main():
50 77 app = MyApp()
51 78 app.parse_command_line()
52 79 if app.config_file:
53 80 app.load_config_file(app.config_file)
54 81 app.init_foo()
55 82 app.init_bar()
56 83 print "app.config:"
57 84 print app.config
58 85
59 86
60 87 if __name__ == "__main__":
61 88 main()
General Comments 0
You need to be logged in to leave comments. Login now