diff --git a/cement/core/handler.py b/cement/core/handler.py index 7bcd25cd..0b58b704 100644 --- a/cement/core/handler.py +++ b/cement/core/handler.py @@ -9,39 +9,51 @@ from ..core import exc, backend, meta LOG = backend.minimal_logger(__name__) class CementBaseHandler(meta.MetaMixin): - """ - All handlers should subclass from here. + """Base handler class that all Cement Handlers should subclass from.""" - Optional / Meta Options: - - label - The identifier of this handler - - interface - The interface that this handler implements. - - config_section - A config [section] to merge config_defaults with. - - Default: . - - config_defaults - A config dictionary that is merged into the applications config - in the [] block. These are defaults and do not - override any existing defaults under that section. - - """ class Meta: + """ + Handler meta-data (can also be passed as keyword arguments to the + parent class). + + """ + label = None + """The string identifier of this handler.""" + interface = None + """The interface that this class implements.""" + config_section = None + """ + A config [section] to merge config_defaults with. + + Note: Though Meta.config_section defaults to None, Cement will + set this to the value of ``.`` if + no section is set by the user/develop. + """ + config_defaults = None + """ + A config dictionary that is merged into the applications config + in the [] block. These are defaults and do not + override any existing defaults under that section. + """ def __init__(self, **kw): super(CementBaseHandler, self).__init__(**kw) self.app = None def _setup(self, app_obj): + """ + The _setup function is called during application initialization and + must 'setup' the handler object making it ready for the framework + or the application to make further calls to it. + + :param app_obj: The application object. + :returns: None + + """ self.app = app_obj if self._meta.config_section is None: self._meta.config_section = "%s.%s" % \ @@ -66,16 +78,14 @@ def get(handler_type, handler_label, *args): Required Arguments: - handler_type - The type of handler (i.e. 'output') - - handler_label - The label of the handler (i.e. 'json') - - Optional Arguments: - - fallback - A fallback value to return if handler_label doesn't exist. + :param handler_type: The type of handler (i.e. 'output') + :type handler_type: str + :param handler_label: The label of the handler (i.e. 'json') + :type handler_label: str + :param fallback: A fallback value to return if handler_label doesn't + exist. + :returns: An uninstantiated handler object + :raises: cement.core.exc.CementRuntimeError Usage: @@ -100,10 +110,10 @@ def list(handler_type): """ Return a list of handlers for a given type. - Required Arguments: - - handler_type - The type of handler (i.e. 'output') + :param handler_type: The type of handler (i.e. 'output') + :returns: List of handlers that match `type`. + :rtype: list + :raises: cement.core.exc.CementRuntimeError """ if handler_type not in backend.handlers: @@ -122,11 +132,10 @@ def define(interface): Define a handler based on the provided interface. Defines a handler type based on .IMeta.label. - Required arguments: - - interface - The handler interface class that defines the interface to be - implemented. + :param interface: The interface class that defines the interface to be + implemented by handlers. + :raises: cement.core.exc.CementInterfaceError + :raises: cement.core.exc.CementRuntimeError Usage: @@ -156,12 +165,9 @@ def defined(handler_type): """ Test whether a handler type is defined. - Required Arguments: - - handler_type - The name or 'type' of the handler (I.e. 'logging'). - - Returns: bool + :param handler_type: The name or 'type' of the handler (I.e. 'logging'). + :returns: True if the handler type is defined, False otherwise. + :rtype: boolean """ if handler_type in backend.handlers: @@ -169,17 +175,16 @@ def defined(handler_type): else: return False -def register(obj): +def register(handler_obj): """ Register a handler object to a handler. If the same object is already registered then no exception is raised, however if a different object attempts to be registered to the same name a CementRuntimeError is raised. - Required Options: - - obj - The handler object to register + :param handler_obj: The uninstantiated handler object to register. + :raises: cement.core.exc.CementInterfaceError + :raises: cement.core.exc.CementRuntimeError Usage: @@ -199,7 +204,7 @@ def register(obj): """ - orig_obj = obj + orig_obj = handler_obj # for checks obj = orig_obj() @@ -249,15 +254,10 @@ def registered(handler_type, handler_label): """ Check if a handler is registered. - Required Arguments: - - handler_type - The type of handler - - handler_label - The label of the handler - - Returns: Boolean + :param handler_type: The type of handler (interface label) + :param handler_label: The label of the handler + :returns: True if the handler is registered, False otherwise + :rtype: boolean """ if handler_type in backend.handlers and \ diff --git a/cement/core/hook.py b/cement/core/hook.py index 76bb5c3b..98b07ec7 100644 --- a/cement/core/hook.py +++ b/cement/core/hook.py @@ -9,11 +9,8 @@ def define(name): """ Define a hook namespace that plugins can register hooks in. - Required arguments: - - name - The name of the hook, stored as hooks['name'] - + :param name: The name of the hook, stored as hooks['name'] + :raises: cement.core.exc.CementRuntimeError Usage: @@ -33,12 +30,10 @@ def defined(hook_name): """ Test whether a hook name is defined. - Required Arguments: - - hook_type - The name of the hook (I.e. 'my_hook_does_awesome_things'). - - Returns: bool + :param hook_name: The name of the hook. + I.e. ``my_hook_does_awesome_things``. + :returns: True if the hook is defined, False otherwise. + :rtype: boolean """ if hook_name in backend.hooks: @@ -51,21 +46,12 @@ def register(name, func, weight=0): Register a function to a hook. The function will be called, in order of weight, when the hook is run. - Required Arguments: - - name - The name of the hook to register too. I.e. 'pre_setup', - 'post_run', etc. - - func - The function to register to the hook. This is an - *un-instantiated*, non-instance method, simple function. - - Optional keyword arguments: - - weight - The weight in which to order the hook function (default: 0) - + :param name: The name of the hook to register too. I.e. ``pre_setup``, + ``post_run``, etc. + :param func: The function to register to the hook. This is an + *un-instantiated*, non-instance method, simple function. + :param weight: The weight in which to order the hook function. + :type weight: integer Usage: @@ -82,7 +68,7 @@ def register(name, func, weight=0): """ if name not in backend.hooks: - LOG.debug("hook name '%s' is not defined!" % name) + LOG.debug("hook name '%s' is not defined! ignoring..." % name) return False LOG.debug("registering hook '%s' from %s into hooks['%s']" % \ @@ -96,15 +82,11 @@ def run(name, *args, **kwargs): Run all defined hooks in the namespace. Yields the result of each hook function run. - Optional arguments: - - name - The name of the hook function - args - Any additional args are passed to the hook function - kwargs - Any kwargs are passed to the hook function - + :param name: The name of the hook function. + :param args: Additional arguments to be passed to the hook functions. + :param kwargs: Additional keyword arguments to be passed to the hook + functions. + :raises: CementRuntimeError Usage: diff --git a/cement/core/interface.py b/cement/core/interface.py index 19f93689..1e8bb65b 100644 --- a/cement/core/interface.py +++ b/cement/core/interface.py @@ -18,10 +18,7 @@ class Attribute(object): """ An interface attribute definition. - Required Arguments: - - description - The description of the attribute. + :param description: The description of the attribute. """ def __init__(self, description): @@ -34,21 +31,11 @@ def validate(interface, obj, members=[], meta=['interface', 'label']): """ A wrapper to validate interfaces. - Required Arguments: - - interface - The interface class to validate against - - obj - The object to validate. - - Optional Arguments: - - members - The object members that must exist. - - meta - The meta object members that must exist. + :param interface: The interface class to validate against + :param obj: The object to validate. + :param members: The object members that must exist. + :param meta: The meta object members that must exist. + :raises: cement.core.exc.CementInterfaceError """ invalid = [] diff --git a/cement/core/log.py b/cement/core/log.py index 5153a318..7e006c58 100644 --- a/cement/core/log.py +++ b/cement/core/log.py @@ -44,8 +44,13 @@ class ILog(interface.Interface): """ # pylint: disable=W0232, C0111, R0903 class IMeta: + """Interface meta-data.""" + label = 'log' + """The string identifier of the interface.""" + validator = log_validator + """The interface validator function.""" # Must be provided by the implementation Meta = interface.Attribute('Handler Meta-data') @@ -56,41 +61,28 @@ class ILog(interface.Interface): must 'setup' the handler object making it ready for the framework or the application to make further calls to it. - Required Arguments: - - app_obj - The application object. - - Returns: n/a + :param app_obj: The application object. """ def clear_loggers(): + """Clear all existing loggers.""" + + def set_level(): """ - Clear all existing loggers. + Set the log level. Must except one of: ``['INFO', 'WARN', 'ERROR', + 'DEBUG', or 'FATAL']``. """ - def set_level(self): - """ - Set the log level. Must except one of: 'INFO', 'WARN', 'ERROR', - 'DEBUG', or 'FATAL'. - - """ - - def level(self): - """ - Return a string representation of the log level. - """ + def level(): + """Return a string representation of the log level.""" - def info(self, msg): + def info(msg): """ Log to the 'INFO' facility. - Required Arguments: - - msg - The message to log. + :param msg: The message to log. """ @@ -98,10 +90,7 @@ class ILog(interface.Interface): """ Log to the 'WARN' facility. - Required Arguments: - - msg - The message to log. + :param msg: The message to log. """ @@ -109,10 +98,7 @@ class ILog(interface.Interface): """ Log to the 'ERROR' facility. - Required Arguments: - - msg - The message to log. + :param msg: The message to log. """ @@ -120,10 +106,7 @@ class ILog(interface.Interface): """ Log to the 'FATAL' facility. - Required Arguments: - - msg - The message to log. + :param msg: The message to log. """ @@ -131,10 +114,7 @@ class ILog(interface.Interface): """ Log to the 'DEBUG' facility. - Required Arguments: - - msg - The message to log. + :param msg: The message to log. """ @@ -149,7 +129,11 @@ class CementLogHandler(handler.CementBaseHandler): class). """ + label = None + """The string identifier of this handler.""" + interface = ILog + """The interface that this class implements.""" def __init__(self, *args, **kw): super(CementLogHandler, self).__init__(*args, **kw) diff --git a/cement/core/output.py b/cement/core/output.py index f27621cb..f408ba19 100644 --- a/cement/core/output.py +++ b/cement/core/output.py @@ -36,11 +36,16 @@ class IOutput(interface.Interface): """ # pylint: disable=W0232, C0111, R0903 class IMeta: + """Interface meta-data.""" + label = 'output' + """The string identifier of the interface.""" + validator = output_validator + """The interface validator function.""" # Must be provided by the implementation - Meta = interface.Attribute('Handler Meta-data') + Meta = interface.Attribute('Handler meta-data') def _setup(app_obj): """ @@ -48,31 +53,19 @@ class IOutput(interface.Interface): must 'setup' the handler object making it ready for the framework or the application to make further calls to it. - Required Arguments: - - app_obj - The application object. + :param app_obj: The application object. - Returns: n/a """ def render(data_dict, template=None): """ Render the data_dict into output in some fashion. - Required Arguments: - - data_dict - The dictionary whose data we need to render into output. - - Optional Paramaters: - - template - A template to use for rendering (in module form). I.e. - myapp.templates.some_command - - - Returns: string or unicode string or None + :param data_dict: The dictionary whose data we need to render into + output. + :param template: A template to use for rendering (in module form). + I.e ``myapp.templates.some_command``. + :returns: string or unicode string or None """ @@ -87,7 +80,11 @@ class CementOutputHandler(handler.CementBaseHandler): class). """ + label = None + """The string identifier of this handler.""" + interface = IOutput + """The interface that this class implements.""" def __init__(self, *args, **kw): super(CementOutputHandler, self).__init__(*args, **kw) diff --git a/cement/core/plugin.py b/cement/core/plugin.py index 39d3be34..70cccbc0 100644 --- a/cement/core/plugin.py +++ b/cement/core/plugin.py @@ -44,7 +44,7 @@ class IPlugin(interface.Interface): validator = plugin_validator # Must be provided by the implementation - Meta = interface.Attribute('Handler Meta-data') + Meta = interface.Attribute('Handler meta-data') loaded_plugins = interface.Attribute('List of loaded plugins') enabled_plugins = interface.Attribute('List of enabled plugins') disabled_plugins = interface.Attribute('List of disabled plugins') @@ -55,23 +55,15 @@ class IPlugin(interface.Interface): must 'setup' the handler object making it ready for the framework or the application to make further calls to it. - Required Arguments: - - app_obj - The application object. - - Returns: n/a - + :param app_obj: The application object. + """ def load_plugin(self, plugin_name): """ Load a plugin whose name is 'plugin_name'. - Required Arguments: - - plugin_name - The name of the plugin to load. + :param plugin_name: The name of the plugin to load. """ @@ -79,10 +71,7 @@ class IPlugin(interface.Interface): """ Load all plugins from plugin_list. - Required Arguments: - - plugin_list - A list of plugin names to load. + :param plugin_list: A list of plugin names to load. """ @@ -98,7 +87,11 @@ class CementPluginHandler(handler.CementBaseHandler): class). """ + label = None + """The string identifier of this handler.""" + interface = IPlugin + """The interface that this class implements.""" def __init__(self, *args, **kw): super(CementPluginHandler, self).__init__(*args, **kw) diff --git a/cement/ext/ext_argparse.py b/cement/ext/ext_argparse.py index a129ded8..754a24ef 100644 --- a/cement/ext/ext_argparse.py +++ b/cement/ext/ext_argparse.py @@ -18,8 +18,13 @@ class ArgParseArgumentHandler(arg.CementArgumentHandler, ArgumentParser): parsed_args = None class Meta: + """Handler meta-data.""" + interface = arg.IArgument + """The interface that this class implements.""" + label = 'argparse' + """The string identifier of the handler.""" def __init__(self, *args, **kw): super(ArgParseArgumentHandler, self).__init__(*args, **kw) @@ -31,12 +36,8 @@ class ArgParseArgumentHandler(arg.CementArgumentHandler, ArgumentParser): is an object. Meaning an argument name of 'foo' will be stored as self.parsed_args.foo. - Required Arguments: - - arg_list - A list of arguments (generally sys.argv) to be parsed. - - Returns: self.parsed_args (object) + :param arg_list: A list of arguments (generally sys.argv) to be parsed. + :returns: object whose members are the arguments parsed. """ self.parsed_args = self.parse_args(arg_list) @@ -51,4 +52,5 @@ class ArgParseArgumentHandler(arg.CementArgumentHandler, ArgumentParser): return super(ArgumentParser, self).add_argument(*args, **kw) def load(): + """Called by the framework when the extension is 'loaded'.""" handler.register(ArgParseArgumentHandler) \ No newline at end of file diff --git a/cement/ext/ext_configparser.py b/cement/ext/ext_configparser.py index e116c8c8..1b206d94 100644 --- a/cement/ext/ext_configparser.py +++ b/cement/ext/ext_configparser.py @@ -23,9 +23,14 @@ class ConfigParserConfigHandler(config.CementConfigHandler, RawConfigParser): RawConfigParser on initialization. """ class Meta: + """Handler meta-data.""" + interface = config.IConfig + """The interface that this handler implements.""" + label = 'configparser' - + """The string identifier of this handler.""" + def __init__(self, *args, **kw): # ConfigParser is not a new style object, so you can't call super() # super(ConfigParserConfigHandler, self).__init__(*args, **kw) @@ -38,20 +43,11 @@ class ConfigParserConfigHandler(config.CementConfigHandler, RawConfigParser): Merge a dictionary into our config. If override is True then existing config values are overridden by those passed in. - Required Arguments: - - dict_obj - A dictionary of configuration keys/values to merge into our - existing config (self). + :param dict_obj: A dictionary of configuration keys/values to merge + into our existing config (self). - Optional Arguments: - - override - Whether or not to override existing values in the config. - Defaults: True. - - - Returns: None + :param override: Whether or not to override existing values in the + config. """ for section in list(dict_obj.keys()): @@ -75,13 +71,8 @@ class ConfigParserConfigHandler(config.CementConfigHandler, RawConfigParser): Parse config file settings from file_path, overwriting existing config settings. If the file does not exist, returns False. - Required Arguments: - - file_path - The file system path to the configuration file. - - - Returns: Bool + :param file_path: The file system path to the configuration file. + :returns: boolean """ file_path = os.path.abspath(os.path.expanduser(file_path)) @@ -97,12 +88,9 @@ class ConfigParserConfigHandler(config.CementConfigHandler, RawConfigParser): """ Return a list of keys within 'section'. - Required Arguments: - - section - The config section (I.e. [block_section]). - - Returns: list + :param section: The config section (I.e. [block_section]). + :returns: List of keys in the `section`. + :rtype: list """ return self.options(section) @@ -111,15 +99,10 @@ class ConfigParserConfigHandler(config.CementConfigHandler, RawConfigParser): """ Return whether or not a 'section' has the given 'key'. - Required Arguments: - - section - The section of the configuration. I.e. [block_section]. - - key - The key within 'section'. - - Returns: bool + :param section: The section of the configuration. I.e. [block_section]. + :param key: The key within 'section'. + :returns: True if the config `section` has `key`. + :rtype: boolean """ if key in self.options(section): @@ -131,7 +114,8 @@ class ConfigParserConfigHandler(config.CementConfigHandler, RawConfigParser): """ Return a list of configuration sections or [blocks]. - Returns: list + :returns: List of sections. + :rtype: list """ return self.sections() @@ -140,10 +124,9 @@ class ConfigParserConfigHandler(config.CementConfigHandler, RawConfigParser): """ Return a dict representation of a section. - Required Arguments: - - section: - The section of the configuration. I.e. [block_section] + :param section: The section of the configuration. I.e. [block_section] + :returns: Dictionary reprisentation of the config section. + :rtype: dict """ dict_obj = dict() @@ -152,7 +135,14 @@ class ConfigParserConfigHandler(config.CementConfigHandler, RawConfigParser): return dict_obj def add_section(self, section): + """ + Adds a block section to the config. + + :param section: The section to add. + + """ super(ConfigParserConfigHandler, self).add_section(section) def load(): + """Called by the framework when the extension is 'loaded'.""" handler.register(ConfigParserConfigHandler) diff --git a/cement/ext/ext_json.py b/cement/ext/ext_json.py index 19d718d7..3bf117e6 100644 --- a/cement/ext/ext_json.py +++ b/cement/ext/ext_json.py @@ -9,8 +9,9 @@ LOG = backend.minimal_logger(__name__) class JsonOutputHandler(output.CementOutputHandler): """ This class implements the :ref:`IOutput ` - interface. It provides JSON output from a data dictionary and uses - `jsonpickle `_ to dump it to STDOUT. + interface. It provides JSON output from a data dictionary using the + `json `_ module of the standard + library. Note: The cement framework detects the '--json' option and suppresses output (same as if passing --quiet). Therefore, if debugging or @@ -19,15 +20,16 @@ class JsonOutputHandler(output.CementOutputHandler): """ class Meta: + """Handler meta-data""" + interface = output.IOutput + """The interface this class implements.""" + label = 'json' + """The string identifier of this handler.""" def __init__(self, *args, **kw): super(JsonOutputHandler, self).__init__(*args, **kw) - self.app = None - - def _setup(self, app_obj): - self.app = app_obj def render(self, data_dict, template=None): """ @@ -35,17 +37,10 @@ class JsonOutputHandler(output.CementOutputHandler): template option is received here per the interface, however this handler just ignores it. - Required Arguments: - - data_dict - The data dictionary to render. - - Optional Arguments: - - template - This option is completely ignored. - - Returns: string (json) + :param data_dict: The data dictionary to render. + :param template: This option is completely ignored. + :returns: A JSON encoded string. + :rtype: str """ LOG.debug("rendering output as Json via %s" % self.__module__) @@ -57,16 +52,26 @@ def add_json_option(app): """ Adds the '--json' argument to the argument object. + :param app: The application object. + """ app.args.add_argument('--json', dest='output_handler', action='store_const', help='toggle json output handler', const='json') def set_output_handler(app): + """ + Overrides the configured output handler if ``--json`` is passed at the + command line. + + :param app: The application object. + + """ if '--json' in app._meta.argv: app._meta.output_handler = 'json' app._setup_output_handler() def load(): + """Called by the framework when the extension is 'loaded'.""" hook.register('post_setup', add_json_option) hook.register('pre_run', set_output_handler) handler.register(JsonOutputHandler) \ No newline at end of file diff --git a/cement/ext/ext_logging.py b/cement/ext/ext_logging.py index f14aaa05..cbb9423e 100644 --- a/cement/ext/ext_logging.py +++ b/cement/ext/ext_logging.py @@ -11,46 +11,6 @@ class LoggingLogHandler(log.CementLogHandler): interface, and sets up the logging facility using the standard Python `logging `_ module. - Optional Arguments / Meta: - - namespace - The logging namespace. Default: application name. - - file - The log file path. Default: None. - - to_console - Whether to log to the console. Default: True. - - rotate - Whether to rotate the log file. Default: False. - - max_bytes - The number of bytes at which to rotate the log file. - Default: 512000. - - max_files - The max number of files to keep when rotation the log file. - Default: 4 - - file_formatter - The logging formatter to use for the log file. - - console_formatter - The logging formatter to use for the console output. - - debug_formatter - The logging formatter to use for debug output. - - clear_loggers - Whether or not to clear previous loggers first. - Default: False. - - level - The level to log at. Must be one of ['INFO', 'WARN', 'ERROR', - 'DEBUG', 'FATAL']. Default: INFO. - - Configuration Options The following configuration options are recognized in this class: @@ -70,9 +30,9 @@ class LoggingLogHandler(log.CementLogHandler): A sample config section (in any config file) might look like: - .. code-block::text + .. code-block:: text - [] + [myapp] debug = True [log] @@ -85,17 +45,43 @@ class LoggingLogHandler(log.CementLogHandler): """ class Meta: + """Handler meta-data.""" + interface = log.ILog + """The interface that this class implements.""" + label = 'logging' + """The string identifier of this handler.""" + namespace = None + """ + The logging namespace. + + Note: Although Meta.namespace defaults to None, Cement will set this + to the application label (CementApp.Meta.label) if not set during + setup. + """ + file_format = "%(asctime)s (%(levelname)s) %(namespace)s : %(message)s" + """The logging format for the file logger.""" + console_format = "%(levelname)s: %(message)s" + """The logging format for the consoler logger.""" + debug_format = "%(asctime)s (%(levelname)s) %(namespace)s : %(message)s" + """The logging format for both file and console if ``debug==True``.""" + clear_loggers = True - + """Whether of not to clear previous loggers first.""" + # These are the default config values, overridden by any '[log]' # section in parsed config files. config_section = 'log' + """ + The section of the application configuration that holds this handlers + configuration. + """ + config_defaults = dict( file=None, level='INFO', @@ -104,7 +90,9 @@ class LoggingLogHandler(log.CementLogHandler): max_bytes=512000, max_files=4, ) - + """ + The default configuration dictionary to populate the ``log`` section. + """ levels = ['INFO', 'WARN', 'ERROR', 'DEBUG', 'FATAL'] @@ -145,7 +133,9 @@ class LoggingLogHandler(log.CementLogHandler): def set_level(self, level): """ Set the log level. Must be one of the log levels configured in - self.levels which are ['INFO', 'WARN', 'ERROR', 'DEBUG', 'FATAL']. + self.levels which are ``['INFO', 'WARN', 'ERROR', 'DEBUG', 'FATAL']``. + + :param level: The log level to set. """ if level not in self.levels: @@ -158,10 +148,8 @@ class LoggingLogHandler(log.CementLogHandler): handler.setLevel(level) def clear_loggers(self): - """ - Clear any previously configured logging namespaces. + """Clear any previously configured logging namespaces.""" - """ if not self._meta.namespace: # _setup() probably wasn't run return @@ -171,10 +159,8 @@ class LoggingLogHandler(log.CementLogHandler): self.backend = logging.getLogger(self._meta.namespace) def _setup_console_log(self): - """ - Add a console log handler. + """Add a console log handler.""" - """ console_handler = logging.StreamHandler() if self.level() == logging.getLevelName(logging.DEBUG): format = logging.Formatter(self._meta.debug_format) @@ -185,10 +171,8 @@ class LoggingLogHandler(log.CementLogHandler): self.backend.addHandler(console_handler) def _setup_file_log(self): - """ - Add a file log handler. + """Add a file log handler.""" - """ file = os.path.abspath(os.path.expanduser(self._meta.file)) log_dir = os.path.dirname(file) if not os.path.exists(log_dir): @@ -214,10 +198,8 @@ class LoggingLogHandler(log.CementLogHandler): self.backend.addHandler(file_handler) def level(self): - """ - Returns the current log level. + """Returns the current log level.""" - """ return logging.getLevelName(self.backend.level) def _get_logging_kwargs(self, namespace, **kw): @@ -237,19 +219,12 @@ class LoggingLogHandler(log.CementLogHandler): """ Log to the INFO facility. - Required Arguments: - - msg - The message the log. - - namespace - A log prefix, generally the module (__name__) that the log is - coming from. Will default to self._meta.namespace if None is - passed. - - Optional Keyword Arguments: - - Keyword arguments are passed on to the backend logging system. + :param msg: The message the log. + :param namespace: A log prefix, generally the module ``__name__`` that + the log is coming from. Will default to self._meta.namespace if + None is passed. + :keyword kw: Keyword arguments are passed on to the backend logging + system. """ kwargs = self._get_logging_kwargs(namespace, **kw) @@ -259,19 +234,12 @@ class LoggingLogHandler(log.CementLogHandler): """ Log to the WARN facility. - Required Arguments: - - msg - The message the log. - - namespace - A log prefix, generally the module (__name__) that the log is - coming from. Will default to self._meta.namespace if None is - passed. - - Optional Keyword Arguments: - - Keyword arguments are passed on to the backend logging system. + :param msg: The message the log. + :param namespace: A log prefix, generally the module ``__name__`` that + the log is coming from. Will default to self._meta.namespace if + None is passed. + :keyword kw: Keyword arguments are passed on to the backend logging + system. """ kwargs = self._get_logging_kwargs(namespace, **kw) @@ -281,19 +249,12 @@ class LoggingLogHandler(log.CementLogHandler): """ Log to the ERROR facility. - Required Arguments: - - msg - The message the log. - - namespace - A log prefix, generally the module (__name__) that the log is - coming from. Will default to self._meta.namespace if None is - passed. - - Optional Keyword Arguments: - - Keyword arguments are passed on to the backend logging system. + :param msg: The message the log. + :param namespace: A log prefix, generally the module ``__name__`` that + the log is coming from. Will default to self._meta.namespace if + None is passed. + :keyword kw: Keyword arguments are passed on to the backend logging + system. """ kwargs = self._get_logging_kwargs(namespace, **kw) @@ -303,19 +264,12 @@ class LoggingLogHandler(log.CementLogHandler): """ Log to the FATAL (aka CRITICAL) facility. - Required Arguments: - - msg - The message the log. - - namespace - A log prefix, generally the module (__name__) that the log is - coming from. Will default to self._meta.namespace if None is - passed. - - Optional Keyword Arguments: - - Keyword arguments are passed on to the backend logging system. + :param msg: The message the log. + :param namespace: A log prefix, generally the module ``__name__`` that + the log is coming from. Will default to self._meta.namespace if + None is passed. + :keyword kw: Keyword arguments are passed on to the backend logging + system. """ kwargs = self._get_logging_kwargs(namespace, **kw) @@ -325,25 +279,19 @@ class LoggingLogHandler(log.CementLogHandler): """ Log to the DEBUG facility. - Required Arguments: - - msg - The message the log. - - namespace - A log prefix, generally the module (__name__) that the log is - coming from. Will default to self._meta.namespace if None is - passed. For debugging, it can be useful to set this to - __file__, though __name__ is much less verbose. - - Optional Keyword Arguments: - - Keyword arguments are passed on to the backend logging system. - + :param msg: The message the log. + :param namespace: A log prefix, generally the module ``__name__`` that + the log is coming from. Will default to self._meta.namespace if + None is passed. For debugging, it can be useful to set this to + ``__file__``, though ``__name__`` is much less verbose. + :keyword kw: Keyword arguments are passed on to the backend logging + system. + """ kwargs = self._get_logging_kwargs(namespace, **kw) self.backend.debug(msg, **kwargs) def load(): + """Called by the framework when the extension is 'loaded'.""" handler.register(LoggingLogHandler) diff --git a/cement/ext/ext_nulloutput.py b/cement/ext/ext_nulloutput.py index 69369980..e5c6927a 100644 --- a/cement/ext/ext_nulloutput.py +++ b/cement/ext/ext_nulloutput.py @@ -12,26 +12,23 @@ class NullOutputHandler(output.CementOutputHandler): """ class Meta: + """Handler meta-data""" + interface = output.IOutput + """The interface this class implements.""" + label = 'null' + """The string identifier of this handler.""" def render(self, data_dict, template=None): """ This implementation does not actually render anything to output, but rather logs it to the debug facility. - Required Arguments: - - data_dict - The data dictionary to render. - - Optional Arguments: - - template - The template parameter is not used by this implementation at - all. - - Returns: None + :param data_dict: The data dictionary to render. + :param template: The template parameter is not used by this + implementation at all. + :returns: None """ Log.debug("not rendering any output to console") @@ -39,4 +36,5 @@ class NullOutputHandler(output.CementOutputHandler): return None def load(): + """Called by the framework when the extension is 'loaded'.""" handler.register(NullOutputHandler) diff --git a/cement/ext/ext_plugin.py b/cement/ext/ext_plugin.py index eb5ece36..5d38087c 100644 --- a/cement/ext/ext_plugin.py +++ b/cement/ext/ext_plugin.py @@ -20,8 +20,13 @@ class CementPluginHandler(plugin.CementPluginHandler): """ class Meta: + """Handler meta-data.""" + interface = plugin.IPlugin + """The interface that this class implements.""" + label = 'cement' + """The string identifier for this class.""" def __init__(self): super(CementPluginHandler, self).__init__() @@ -84,14 +89,10 @@ class CementPluginHandler(plugin.CementPluginHandler): Load a plugin from file within a plugin directory rather than a python package within sys.path. - Required Arguments: - - plugin_name - The name of the plugin, also the name of the file with '.py' - appended to the name. - - plugin_dir - The filesystem directory path where to find the file. + :param plugin_name: The name of the plugin, also the name of the file + with '.py' appended to the name. + :param plugin_dir: The filesystem directory path where to find the + file. """ full_path = os.path.join(plugin_dir, "%s.py" % plugin_name) @@ -114,17 +115,15 @@ class CementPluginHandler(plugin.CementPluginHandler): Load a plugin from a python package. Returns True if no ImportError is encountered. - Required Arguments: - - plugin_name - The name of the plugin, also the name of the module to load - from base_package. I.e. 'myapp.bootstrap.myplugin'. - - base_package - The base python package to load the plugin module from. I.e. - 'myapp.bootstrap' or similar. - - Returns: Bool + :param plugin_name: The name of the plugin, also the name of the + module to load from base_package. + I.e. ``myapp.bootstrap.myplugin`` + :type plugin_name: str + :param base_package: The base python package to load the plugin module from. I.e. + 'myapp.bootstrap' or similar. + :type base_package: str + :returns: True is the plugin was loaded, False otherwise + :raises: ImportError """ if base_package is None: @@ -154,10 +153,9 @@ class CementPluginHandler(plugin.CementPluginHandler): Upon successful loading of a plugin, the plugin name is appended to the self._loaded_plugins list. - Required Arguments: - - plugin_name - The name of the plugin to load. + :param plugin_name: The name of the plugin to load. + :type plugin_name: str + :raises: cement.core.exc.CementRuntimeError """ LOG.debug("loading application plugin '%s'" % plugin_name) @@ -166,10 +164,8 @@ class CementPluginHandler(plugin.CementPluginHandler): if self._load_plugin_from_dir(plugin_name, self.load_dir): self._loaded_plugins.append(plugin_name) - return True elif self._load_plugin_from_bootstrap(plugin_name, self.bootstrap): self._loaded_plugins.append(plugin_name) - return True else: raise exc.CementRuntimeError("Unable to load plugin '%s'." % plugin_name) @@ -179,10 +175,7 @@ class CementPluginHandler(plugin.CementPluginHandler): Load a list of plugins. Each plugin name is passed to self.load_plugin(). - Required Arguments: - - plugin_list - A list of plugin names to load. + :param plugin_list: A list of plugin names to load. """ for plugin_name in plugin_list: @@ -190,15 +183,19 @@ class CementPluginHandler(plugin.CementPluginHandler): @property def loaded_plugins(self): + """List of plugins that have been loaded.""" return self._loaded_plugins @property def enabled_plugins(self): + """List of plugins that are enabled (not necessary loaded yet).""" return self._enabled_plugins @property def disabled_plugins(self): + """List of disabled plugins""" return self._disabled_plugins def load(): + """Called by the framework when the extension is 'loaded'.""" handler.register(CementPluginHandler) diff --git a/cement/utils/fs.py b/cement/utils/fs.py index 6fbb876d..726d54d3 100644 --- a/cement/utils/fs.py +++ b/cement/utils/fs.py @@ -8,10 +8,8 @@ def abspath(path): Return an absolute path, while also expanding the '~' user directory shortcut. - Required Arguments: - - path - The original path to expand. + :param path: The original path to expand. + :rtype: str """ return os.path.abspath(os.path.expanduser(path)) @@ -21,12 +19,9 @@ def backup(path): Rename a file or directory safely without overwriting an existing backup of the same name. - Required Arguments: - - path - The path to the file or directory to make a backup of. - - Return: str (new path of backed up file/directory) + :param path: The path to the file or directory to make a backup of. + :returns: The new path of backed up file/directory + :rtype: str """ count = -1 diff --git a/cement/utils/misc.py b/cement/utils/misc.py index 7a861ba9..e84dad0d 100644 --- a/cement/utils/misc.py +++ b/cement/utils/misc.py @@ -3,6 +3,11 @@ def is_true(item): """ Given a value, determine if it is one of [True, 'True', 'true', 1, '1']. + + :param item: The item to convert to a boolean. + :returns: True if `item` is in ``[True, 'True', 'true', 1, '1']``, False + otherwise. + :rtype: boolean """ if item in [True, 'True', 'true', 1, '1']: diff --git a/cement/utils/shell.py b/cement/utils/shell.py index b501ef10..dc60fd89 100644 --- a/cement/utils/shell.py +++ b/cement/utils/shell.py @@ -6,16 +6,12 @@ def exec_cmd(cmd_args, shell=False): """ Execute a shell call using Subprocess. - Required Arguments: - - cmd_args - List of command line arguments. - - shell - Boolean option. See `Subprocess `_ - Default: False - - Return: tuple (stdout, stderr, return_code) + :param cmd_args: List of command line arguments. + :type cmd_args: list + :param shell: See `Subprocess `_ + :type shell: boolean + :returns: The (stdout, stderror, return_code) of the command + :rtype: tuple """ proc = Popen(cmd_args, stdout=PIPE, stderr=PIPE, shell=shell) @@ -28,16 +24,12 @@ def exec_cmd2(cmd_args, shell=False): Similar to exec_cmd, however does not capture stdout, stderr (therefore allowing it to print to console). - Required Arguments: - - cmd_args - List of command line arguments. - - shell - Boolean option. See `Subprocess `_ - Default: False - - Return: int (return_code) + :param cmd_args: List of command line arguments. + :type cmd_args: list + :param shell: See `Subprocess `_ + :type shell: boolean + :returns: The integer return code of the command. + :rtype: int """ proc = Popen(cmd_args, shell=shell) diff --git a/doc/source/api/core/meta.rst b/doc/source/api/core/meta.rst index b0d38a0c..ac1369e7 100644 --- a/doc/source/api/core/meta.rst +++ b/doc/source/api/core/meta.rst @@ -6,5 +6,4 @@ .. automodule:: cement.core.meta :members: :undoc-members: - :private-members: :show-inheritance: \ No newline at end of file diff --git a/tests/ext/logging_tests.py b/tests/ext/logging_tests.py index 6fb1455e..8c2803c0 100644 --- a/tests/ext/logging_tests.py +++ b/tests/ext/logging_tests.py @@ -28,7 +28,9 @@ class LoggingExtTestCase(test.CementTestCase): app.setup() def test_alternate_namespaces(self): - app = self.make_app() + defaults = backend.defaults('myapp', 'log') + defaults['log']['to_console'] = False + app = self.make_app(config_defaults=defaults) app.setup() app.log.info('TEST', extra=dict(namespace=__name__)) app.log.warn('TEST', extra=dict(namespace=__name__))