diff --git a/IPython/config/application.py b/IPython/config/application.py new file mode 100644 index 0000000..c35bc41 --- /dev/null +++ b/IPython/config/application.py @@ -0,0 +1,108 @@ +# encoding: utf-8 +""" +A base class for a configurable application. + +Authors: + +* Brian Granger +""" + +#----------------------------------------------------------------------------- +# Copyright (C) 2008-2011 The IPython Development Team +# +# Distributed under the terms of the BSD License. The full license is in +# the file COPYING, distributed as part of this software. +#----------------------------------------------------------------------------- + +#----------------------------------------------------------------------------- +# Imports +#----------------------------------------------------------------------------- + +from copy import deepcopy +import sys + +from IPython.config.configurable import Configurable +from IPython.utils.traitlets import ( + Unicode, List +) +from IPython.config.loader import ( + KeyValueConfigLoader, PyFileConfigLoader +) + +#----------------------------------------------------------------------------- +# Application class +#----------------------------------------------------------------------------- + + +class Application(Configurable): + + # The name of the application, will usually match the name of the command + # line application + app_name = Unicode(u'application') + + # The description of the application that is printed at the beginning + # of the help. + description = Unicode(u'This is an application.') + + # A sequence of Configurable subclasses whose config=True attributes will + # be exposed at the command line (shortnames and help). + classes = List([]) + + # The version string of this application. + version = Unicode(u'0.0') + + def __init__(self, **kwargs): + Configurable.__init__(self, **kwargs) + # Add my class to self.classes so my attributes appear in command line + # options. + self.classes.insert(0, self.__class__) + + def print_help(self): + """Print the help for each Configurable class in self.classes.""" + for cls in self.classes: + cls.class_print_help() + print + + def print_description(self): + """Print the application description.""" + print self.description + print + + def print_version(self): + """Print the version string.""" + print self.version + + def update_config(self, config): + # Save a copy of the current config. + newconfig = deepcopy(self.config) + # Merge the new config into the current one. + newconfig._merge(config) + # Save the combined config as self.config, which triggers the traits + # events. + self.config = config + + def parse_command_line(self, argv=None): + """Parse the command line arguments.""" + if argv is None: + argv = sys.argv[1:] + + if '-h' in argv or '--h' in argv: + self.print_description() + self.print_help() + sys.exit(1) + + if '--version' in argv: + self.print_version() + sys.exit(1) + + loader = KeyValueConfigLoader(argv=argv, classes=self.classes) + config = loader.load_config() + self.update_config(config) + + def load_config_file(self, filename, path=None): + """Load a .py based config file by filename and path.""" + # TODO: this raises IOError if filename does not exist. + loader = PyFileConfigLoader(filename, path=path) + config = loader.load_config() + self.update_config(config) + diff --git a/IPython/config/configurable.py b/IPython/config/configurable.py index 12abd1c..7d04db1 100755 --- a/IPython/config/configurable.py +++ b/IPython/config/configurable.py @@ -22,9 +22,7 @@ Authors: from copy import deepcopy import datetime -from weakref import WeakValueDictionary -from IPython.utils.importstring import import_item from loader import Config from IPython.utils.traitlets import HasTraits, Instance from IPython.utils.text import indent @@ -152,13 +150,18 @@ class Configurable(HasTraits): @classmethod def class_get_help(cls): + """Get the help string for this class in ReST format.""" cls_traits = cls.class_traits(config=True) final_help = [] - final_help.append('%s options' % cls.__name__) - final_help.append(len(final_help[0])*'-') + final_help.append(u'%s options' % cls.__name__) + final_help.append(len(final_help[0])*u'-') for k, v in cls_traits.items(): help = v.get_metadata('help') - final_help.append(k + " : " + v.__class__.__name__) + shortname = v.get_metadata('shortname') + header = "%s.%s : %s" % (cls.__name__, k, v.__class__.__name__) + if shortname is not None: + header += " (shortname=" + shortname + ")" + final_help.append(header) if help is not None: final_help.append(indent(help)) return '\n'.join(final_help) diff --git a/docs/examples/core/appconfig.py b/docs/examples/core/appconfig.py index 28644ce..7c8954f 100644 --- a/docs/examples/core/appconfig.py +++ b/docs/examples/core/appconfig.py @@ -1,10 +1,10 @@ import sys from IPython.config.configurable import Configurable +from IPython.config.application import Application from IPython.utils.traitlets import ( Bool, Unicode, Int, Float, List ) -from IPython.config.loader import KeyValueConfigLoader class Foo(Configurable): @@ -18,35 +18,19 @@ class Bar(Configurable): enabled = Bool(True, config=True, shortname="bar-enabled", help="Enable bar.") -class MyApp(Configurable): +class MyApp(Application): - app_name = Unicode(u'myapp', config=True, shortname="myapp", help="The app name.") + app_name = Unicode(u'myapp') running = Bool(False, config=True, shortname="running", help="Is the app running?") classes = List([Bar, Foo]) - - def __init__(self, **kwargs): - Configurable.__init__(self, **kwargs) - self.classes.insert(0, self.__class__) - - def print_help(self): - for cls in self.classes: - cls.class_print_help() - print - - def parse_command_line(self, argv=None): - if argv is None: - argv = sys.argv[1:] - if '-h' in argv or '--h' in argv: - self.print_help() - sys.exit(1) - loader = KeyValueConfigLoader(argv=argv, classes=self.classes) - config = loader.load_config() - self.config = config + config_file = Unicode(u'', config=True, shortname="config-file", help="Load this config file") def main(): app = MyApp() app.parse_command_line() + if app.config_file: + app.load_config_file(app.config_file) print "app.config:" print app.config