Skip to content

Commit

Permalink
Merge remote-tracking branch 'remotes/origin/master' into index_recor…
Browse files Browse the repository at this point in the history
…ding
  • Loading branch information
Christian-B committed Feb 28, 2018
2 parents 083189b + cb55150 commit 7acc85a
Show file tree
Hide file tree
Showing 37 changed files with 891 additions and 687 deletions.
17 changes: 7 additions & 10 deletions spinn_utilities/abstract_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,14 @@
def abstractmethod(funcobj):
""" A decorator indicating abstract methods.
Requires that the metaclass is AbstractBase or derived from it. A\
class that has a metaclass derived from AbstractBase cannot be\
Requires that the metaclass is :py:class:AbstractBase or derived from it.\
A class that has a metaclass derived from :py:class:AbstractBase cannot be\
instantiated unless all of its abstract methods are overridden.\
The abstract methods can be called using any of the normal\
'super' call mechanisms.
Usage:
Usage::
::
@add_metaclass(AbstractBase)
class C:
@abstractmethod
Expand All @@ -28,25 +27,23 @@ def my_abstract_method(self, ...):
class abstractproperty(property):
""" A decorator indicating abstract properties.
Requires that the metaclass is AbstractBase or derived from it. A\
class that has a metaclass derived from AbstractBase cannot be\
Requires that the metaclass is :py:class:AbstractBase or derived from it.\
A class that has a metaclass derived from :py:class:AbstractBase cannot be\
instantiated unless all of its abstract properties are overridden.\
The abstract properties can be called using any of the normal\
'super' call mechanisms.
Usage:
Usage::
::
@add_metaclass(AbstractBase)
class C:
@abstractproperty
def my_abstract_property(self):
...
This defines a read-only property; you can also define a read-write\
abstract property using the 'long' form of property declaration:
abstract property using the 'long' form of property declaration::
::
@add_metaclass(AbstractBase)
class C:
def getx(self): ...
Expand Down
119 changes: 65 additions & 54 deletions spinn_utilities/conf_loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,36 +8,33 @@
import sys

from spinn_utilities import log
from spinn_utilities.configs.camel_case_config_parser import \
CamelCaseConfigParser
from spinn_utilities.configs.case_sensitive_parser import CaseSensitiveParser
from spinn_utilities.configs.unexpected_config_exception import \
UnexpectedConfigException
from spinn_utilities.configs.no_config_found_exception import \
NoConfigFoundException
from spinn_utilities.configs import \
CamelCaseConfigParser, CaseSensitiveParser
from spinn_utilities.configs import \
NoConfigFoundException, UnexpectedConfigException

logger = logging.getLogger(__name__)


def install_cfg_and_IOError(filename, defaults, config_locations):
"""
Installs a local config based on the tamplates and thorws an Error
This method is called when no user config is found.
""" Installs a local configuration file based on the templates and raises\
an exception.
It will create a file in the users home directory based on the defaults.
This method is called when no user configuration file is found.
Then it prints a helpful messages and thros and error with the same message
It will create a file in the users home directory based on the defaults.\
Then it prints a helpful message and throws an error with the same message.
:param filename: Name under which to save the new config file
:param filename: Name under which to save the new configuration file
:type filename: str
:param defaults: List of full paths to the default config files.\
:param defaults: List of full paths to the default configuration files.\
Each of which MUST have an associated template file with exactly the\
same path plus .template
:type defaults: List[str]
:param config_locations: List of paths the user configs where looked for,\
Onlty used for the message
:raise NoConfigFoundException: Always raised
:type defaults: list(str)
:param config_locations: List of paths where the user configuration files\
were looked for. Only used for the message
:type config_locations: list(str)
:raise spinn_utilities.configs.NoConfigFoundException: Always raised
"""
home_cfg = os.path.join(os.path.expanduser("~"), ".{}".format(filename))

Expand Down Expand Up @@ -72,7 +69,11 @@ def install_cfg_and_IOError(filename, defaults, config_locations):
def logging_parser(config):
""" Create the root logger with the given level.
Create filters based on logging levels
Create filters based on logging levels
.. note::
You do not normally need to call this function; it is used\
automatically to parse Logging configuration sections.
"""
try:
if config.getboolean("Logging", "instantiate"):
Expand All @@ -87,7 +88,7 @@ def logging_parser(config):

def _outdated_config_section(validation_config, defaults, config, skip,
user_sections, section):
"""Helper for _outdated_config"""
"""Helper for :py:func:_outdated_config"""
if section in user_sections:
print "Section [{}] should be kept as these need to be set " \
"by the user".format(section)
Expand Down Expand Up @@ -135,33 +136,33 @@ def _outdated_config_section(validation_config, defaults, config, skip,


def _outdated_config(cfg_file, validation_cfg, default_cfg):
"""
Prints why a config file is outdated and raises an exception
""" Prints why a configuration file is outdated and raises an exception.
Reads a config file by itself (Without others)
Reads a configuration file by itself (Without others)
Reports errors in this config based on the validation_cfg and the\
defaults_configs
Reports errors in this configuration file based on the validation_cfg and\
the default_cfg
Reports any values listed as PreviousValues.\
These are specific values in specific options no longer supported.\
For example old algorithm names
These are specific values in specific options no longer supported.\
For example old algorithm names.
Checks all sections not defined as UserSections (Default Machine)\
i.e., ones the user is expected to change
i.e., ones the user is expected to change
Any sect specific list as Dead will be reported
Any section specifically listed as Dead will be reported
Any sect in the default config is compared.
reporting any unexpected values
reporting the smaller of values non default or values same as default
Any section in the default configuration file is compared, reporting
* any unexpected values
* the smaller of values non default or values same as default
Any other sect is ignored as assumed being used by an extension
Any other section is ignored as assumed being used by an extension
:param cfg_file: Path to be checked
:param validation_cfg: Path containing the validation rules
:param default_cfg: List of Paths to default_cfg
:return:
:return: an exception
:rtype: spinn_utilities.configs.UnexpectedConfigException
"""

try:
Expand Down Expand Up @@ -201,25 +202,24 @@ def _outdated_config(cfg_file, validation_cfg, default_cfg):


def _check_config(cfg, cfg_file, validation_cfg, default_cfg):
"""
Checks the cfg read up to this point to see if it is outdated
""" Checks the configuration read up to this point to see if it is outdated
Once one difference is found a full reports is generated and an error\
raised
raised.
Any sect specific list as Dead will cause a error
Any section specifically listed as Dead will cause a error
Any sect in the default_cfg should not have extra values.\
It will never have less as the default_cfg are in the cfg
Any section in the default_cfg should not have extra values.\
It will never have less as the default_cfg are in the cfg
Errors on any values listed as PreviousValues.\
These are specific values in specific options no longer supported.\
For example old algorithm names
These are specific values in specific options no longer supported.\
For example old algorithm names
:param cfg: Config as read in up to this point
:param cfg: Configuration as read in up to this point
:param cfg_file: Path of last file read in
:param validation_cfg: Path containing the validation rules
:param default_configs: List of Paths to default_cfg
:param default_cfg: The list of paths to default configurations
"""
if validation_cfg is None or default_cfg is None:
return
Expand Down Expand Up @@ -251,13 +251,13 @@ def _check_config(cfg, cfg_file, validation_cfg, default_cfg):


def _read_a_config(config, cfg_file, validation_cfg, default_cfg):
""" Reads in a config file and then directly its machine_spec_file
""" Reads in a configuration file and then directly its machine_spec_file
:param config: config to do the reading
:param config: configuration to be updated by the reading of a file
:param cfg_file: path to file which should be read in
:param validation_cfg: ?
:param default_cfg: ?
:return: list of files read including and machine_spec_files
:param validation_cfg: Path containing the validation rules
:param default_cfg: The list of paths to default configurations
:return: None
"""
config.read(cfg_file)
_check_config(config, cfg_file, validation_cfg, default_cfg)
Expand Down Expand Up @@ -290,13 +290,24 @@ def _config_locations(filename):


def load_config(filename, defaults, config_parsers=None, validation_cfg=None):
""" Load the configuration
""" Load the configuration.
:param filename: The base name of the configuration file(s). Should not\
include any path components.
:type filename: str
:param defaults: The list of files to get default configurations from.
:type defaults: list(str)
:param config_parsers:\
The parsers to parse the cfg with, as a list of\
(section name, parser); cfg will only be parsed if the\
section_name is found in the configuration files already loaded
The parsers to parse the sections of the configuration file with, as\
a list of (section name, parser); a configuration section will only\
be parsed if the section_name is found in the configuration files\
already loaded. The standard logging parser is appended to (a copy\
of) this list.
:type config_parsers: list of (str, ConfigParser)
:param validation_cfg: The list of files to read a validation\
configuration from. If omitted, no such validation is performed.
:type validation_cfg: list(str)
:return: the fully-loaded and checked configuration
"""

cfg = CamelCaseConfigParser()
Expand Down
8 changes: 8 additions & 0 deletions spinn_utilities/configs/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from .camel_case_config_parser import CamelCaseConfigParser
from .case_sensitive_parser import CaseSensitiveParser
from .no_config_found_exception import NoConfigFoundException
from .unexpected_config_exception import UnexpectedConfigException

__all__ = [
"CamelCaseConfigParser", "CaseSensitiveParser",
"NoConfigFoundException", "UnexpectedConfigException"]
2 changes: 2 additions & 0 deletions spinn_utilities/configs/camel_case_config_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@


class CamelCaseConfigParser(RawConfigParser):
# RawConfigParser is a classobj in Python 2.7, not a type (i.e., it
# doesn't inherit from object), and so cannot be used with super().

def optionxform(self, optionstr):
lower = optionstr.lower()
Expand Down
15 changes: 5 additions & 10 deletions spinn_utilities/executable_finder.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@ class ExecutableFinder(object):
""" Manages a set of folders in which to search for binaries,\
and allows for binaries to be discovered within this path
"""
__slots__ = [
"_binary_search_paths"]

def __init__(self, binary_search_paths):
"""
:param binary_search_paths:\
The initial set of folders to search for binaries.
:type binary_search_paths: iterable of str
Expand All @@ -32,25 +33,19 @@ def add_path(self, path):

@property
def binary_paths(self):
output = ""
separator = ""
for path in self._binary_search_paths:
output += separator + path
separator = " : "
return output
return " : ".join(self._binary_search_paths)

def get_executable_path(self, executable_name):
""" Finds an executable within the set of folders. The set of folders\
""" Finds an executable within the set of folders. The set of folders\
is searched sequentially and the first match is returned.
:param executable_name: The name of the executable to find
:type executable_name: str
:return:\
The full path of the discovered executable, or None if no \
The full path of the discovered executable, or ``None`` if no \
executable was found in the set of folders
:rtype: str
"""

# Loop through search paths
for path in self._binary_search_paths:
# Rebuild filename
Expand Down

0 comments on commit 7acc85a

Please sign in to comment.