示例#1
0
class CommandModule(object):

    _log = log_.get_log("module")

    def __init__(self, path):
        self._path = os.path.abspath(path)
        self._namespace = None
        self._loaded = False

    def __str__(self):
        return "%s(%r)" % (self.__class__.__name__, os.path.basename(
            self._path))

    def load(self):
        self._log.error("%s: Loading module: %r" % (self, self._path))

        # Prepare namespace in which to execute the
        namespace = {}
        namespace["__file__"] = self._path

        # Attempt to execute the module; handle any exceptions.
        try:
            execfile(self._path, namespace)
        except Exception, e:
            self._log.error("%s: Error loading module: %s" % (self, e))
            self._loaded = False
            return

        self._loaded = True
        self._namespace = namespace
示例#2
0
class CommandModuleDirectory(object):

    _log = log_.get_log("directory")

    def __init__(self, path, excludes=None):
        self._path = os.path.abspath(path)
        self._excludes = excludes
        self._modules = {}

    def load(self):
        valid_paths = self._get_valid_paths()

        # Remove any deleted modules.
        for path, module in self._modules.items():
            if path not in valid_paths:
                del self._modules[path]
                module.unload()

        # Add any new modules.
        for path in valid_paths:
            if path not in self._modules:
                module = CommandModule(path)
                module.load()
                self._modules[path] = module
            else:
                module = self._modules[path]
                module.check_freshness()

    def _get_valid_paths(self):
        valid_paths = []
        for filename in os.listdir(self._path):
            path = os.path.abspath(join(self._path, filename))
            if not os.path.isfile(path):
                continue
            if not os.path.splitext(path)[1] == ".py":
                continue
            if path in self._excludes:
                continue
            valid_paths.append(path)
        self._log.error("valid paths: %r" % valid_paths)
        return valid_paths
示例#3
0
class Config(object):
    """
        Configuration class for storing program settings.

        Constructor argument:
         - *name* (*str*) --
           the name of this configuration object.

        This class can contain zero or more :class:`Section` instances, 
        each of which can contain zero or more :class:`Item` instances. 
        It is these items which store the actual configuration settings. 
        The sections merely divide the items up into groups, so that 
        different configuration topics can be split for easy readability.

  """

    _configs_by_name = {}
    _log = log_.get_log("config")

    #-----------------------------------------------------------------------

    @classmethod
    def get_by_name(cls, name):
        try:
            return cls._configs_by_name[name]
        except KeyError:
            return None

    @classmethod
    def get_instances(cls):
        instances = cls._configs_by_name.items()
        instances.sort()
        return [instance for name, instance in instances]

    #-----------------------------------------------------------------------

    def __init__(self, name):
        set_ = object.__setattr__
        set_(self, "name", name)
        set_(self, "_sections", {})
        set_(self, "_sections_list", [])
        set_(self, "_mode", _init)
        set_(self, "module_path", None)
        set_(self, "config_path", None)

        Config._configs_by_name[name] = self

    def _set_mode(self, mode):
        object.__setattr__(self, "_mode", mode)
        for n, s in self._sections_list:
            s._set_mode(mode)

    def __getattr__(self, name):
        if name in self._sections: return self._sections[name]
        else: raise AttributeError(name)

    def __setattr__(self, name, value):
        if self._mode == _init:
            if isinstance(value, Section):
                self._sections[name] = value
                self._sections_list.append((name, value))
            else:
                raise TypeError("Invalid type %s, expecting Section." %
                                type(value))
        else:
            raise AttributeError(name)

    def load(self, path=None):
        """
            Load the configuration file at the given *path*, or
            look for a configuration file associated with the calling
            module.

             - *path* (*str*, default: *None*) --
               path to the configuration file to load.  If *None*,
               then a path is generated from the calling module's
               file name by replacing its extension with ".txt".

            If the *path* is a file, it is loaded.  On the other hand,
            if it does not exist or is not a file, nothing is loaded
            and this configuration's defaults remain in place.

        """
        self._set_mode(_load)
        if not path:
            caller_frame = inspect.currentframe().f_back
            caller_file = caller_frame.f_globals["__file__"]
            module_base, module_ext = os.path.splitext(caller_file)
            path = module_base + ".txt"
            if module_ext in (".pyc", ".pyo"):
                module_ext = ".py"
            object.__setattr__(self, "module_path", module_base + module_ext)
        object.__setattr__(self, "config_path", path)

        if os.path.exists(path):
            namespace = self.load_from_file(path)
        else:
            namespace = None
        self._set_mode(_done)

        return namespace

    def load_from_file(self, path):
        namespace = dict(self._sections)
        for name, section in self._sections_list:
            section.update_namespace(namespace)

        try:
            execfile(path, namespace)
#        except ConfigError, e:
        except Exception, e:
            print "exception:", e
            t, v, tb = sys.exc_info()
            frames = traceback.extract_tb(tb)
            relevant_frames = []
            error_line = "<unknown>"
            include_all = False
            for frame in frames:
                filename, line, function, text = frame
                print "frame:", frame

                if not include_all:
                    file1 = os.path.basename(filename)
                    file2 = os.path.basename(path)
                    if file1 == file2:
                        include_all = True
                        error_line = line

                if include_all:
                    relevant_frames.append(frame)

            self._log.error("An error occurred in the %s file at line %s." %
                            (path, error_line))
            self._log.error("The error message was: %s" % e)
            formatted = traceback.format_list(relevant_frames)
            lines = "\n".join(formatted).splitlines()
            for line in lines:
                self._log.error("    " + line)

        return namespace
示例#4
0
class Compound(elements_.Alternative):

    _log = log_.get_log("compound.parse")
    _parser = parser_.Parser(stuff, _log)

    def __init__(self,
                 spec,
                 extras=None,
                 actions=None,
                 name=None,
                 value=None,
                 value_func=None,
                 elements=None):
        self._spec = spec
        self._value = value
        self._value_func = value_func

        if extras is None: extras = {}
        if actions is None: actions = {}
        if elements is None: elements = {}

        # Convert extras argument from sequence to mapping.
        if isinstance(extras, (tuple, list)):
            mapping = {}
            for element in extras:
                if not isinstance(element, elements_.ElementBase):
                    self._log.error("Invalid extras item: %s" % element)
                    raise TypeError("Invalid extras item: %s" % element)
                if not element.name:
                    self._log.error("Extras item does not have a name: %s" %
                                    element)
                    raise TypeError("Extras item does not have a name: %s" %
                                    element)
                if element.name in mapping:
                    self._log.warning(
                        "Multiple extras items with the same name: %s" %
                        element)
                mapping[element.name] = element
            extras = mapping
        elif not isinstance(extras, dict):
            self._log.error("Invalid extras argument: %s" % extras)
            raise TypeError("Invalid extras argument: %s" % extras)

        # Temporary transition code so that both "elements" and "extras"
        #  are supported as keyword arguments.
        if extras and elements:
            extras = dict(extras)
            extras.update(elements)
        elif elements:
            extras = elements
        self._extras = extras

        # This solution is non-ideal as "stuff" is a global instance.
        stuff.set_elements(extras)
        stuff.set_actions(actions)

        element = self._parser.parse(spec)
        if not element:
            self._log.error("Invalid compound spec: %r" % spec)
            raise SyntaxError("Invalid compound spec: %r" % spec)
        elements_.Alternative.__init__(self, (element, ), name=name)

    def __str__(self):
        arguments = ["%r" % self._spec]
        if self.name: arguments.append("name=%r" % self.name)
        arguments = ", ".join(arguments)
        return "%s(%s)" % (self.__class__.__name__, arguments)

    def value(self, node):
        if self._value_func is not None:
            extras = {}
            for name, element in self._extras.iteritems():
                extra_node = node.get_child_by_name(name, shallow=True)
                if not extra_node: continue
                extras[name] = extra_node.value()
            try:
                value = self._value_func(node, extras)
            except Exception, e:
                self._log.warning("Exception from value_func: %s" % e)
                raise
            return value
        elif self._value is not None:
            return self._value
示例#5
0
class CompilerBase(object):

    _log = log_.get_log("engine.compiler")

    element_compilers = [
        (elements_.Sequence,
         lambda s, e, *a, **k: s._compile_sequence(e, *a, **k)),
        (elements_.Alternative,
         lambda s, e, *a, **k: s._compile_alternative(e, *a, **k)),
        (elements_.Optional,
         lambda s, e, *a, **k: s._compile_optional(e, *a, **k)),
        (elements_.Literal,
         lambda s, e, *a, **k: s._compile_literal(e, *a, **k)),
        (elements_.RuleRef,
         lambda s, e, *a, **k: s._compile_rule_ref(e, *a, **k)),
        (elements_.ListRef,
         lambda s, e, *a, **k: s._compile_list_ref(e, *a, **k)),
        (elements_.Dictation,
         lambda s, e, *a, **k: s._compile_dictation(e, *a, **k)),
        (elements_.Impossible,
         lambda s, e, *a, **k: s._compile_impossible(e, *a, **k)),
    ]

    #-----------------------------------------------------------------------

    def __str__(self):
        return "%s()" % self.__class__.__name__

    #-----------------------------------------------------------------------
    # Methods for compiling grammars.

    def compile_grammar(self, grammar, *args, **kwargs):
        raise NotImplementedError("Compiler %s not implemented." % self)

    #-----------------------------------------------------------------------
    # Methods for compiling elements.

    def compile_element(self, element, *args, **kwargs):
        # Look for a compiler method to handle the given element.
        for element_type, compiler in self.element_compilers:
            if isinstance(element, element_type):
                compiler(self, element, *args, **kwargs)
                return

        # Didn't find a compiler method for this element type.
        raise NotImplementedError("Compiler %s not implemented"
                                  " for element type %s." % (self, element))

    #-----------------------------------------------------------------------

    def _compile_unknown_element(self, element, *args, **kwargs):
        raise NotImplementedError("Compiler %s not implemented"
                                  " for element type %s." % (self, element))

    _compile_sequence = _compile_unknown_element
    _compile_alternative = _compile_unknown_element
    _compile_optional = _compile_unknown_element
    _compile_literal = _compile_unknown_element
    _compile_rule_ref = _compile_unknown_element
    _compile_list_ref = _compile_unknown_element
    _compile_dictation = _compile_unknown_element
    _compile_impossible = _compile_unknown_element