コード例 #1
0
    def __init__(self, raw_pattern, raw_previous, weight, alternates,
                 method, rulename):
        """ Create a new Rule object based on information supplied to the
        @rule decorator. Arguments:
        raw_pattern - simplified regular expression string supplied to @rule
        raw_previous - simplified regular expression string supplied to @rule
        weight -  weight supplied to @rule
        alternates - dictionary of variable names and values that can
                   be substituted in the patterns
        method - reference to method decorated by @rule
        rulename - modulename.classname.methodname, used to make better
                 error messages

        Raises PatternError, PatternVariableNotFoundError,
               PatternVariableValueError
        """
        try:
            previous = ""
            if not raw_pattern:
                raise PatternError("Empty string found")
            self.pattern = Pattern(raw_pattern, alternates)
            previous = "previous "
            self.previous = Pattern(raw_previous, alternates)
        except (TypeError, PatternError, PatternVariableValueError,
                PatternVariableNotFoundError) as e:
            msg = " in {0}pattern of {1}".format(previous, rulename)
            e.args = (e.args[0] + msg,) + e.args[1:]
            raise

        self.weight = weight
        self.method = method
        self.rulename = rulename
コード例 #2
0
    def _parse_alternates(self, alternates, script_class_name):
        """Construct Pattern objects for all the values in the alternates
        instance variable (hopefully a dictionary) of a Script
        subclass, and construct a dictionary of the keys from
        alternates and the pattern object. Wrap that in another
        dictionary keyed by 'a' so it can be used by %a:varname in
        other patterns.

        """
        valid = {}
        k = ""
        try:
            for k, v in alternates.items():
                valid[k] = Pattern(v, simple=True).formatted_pattern
        except Exception as e:
            msg = " in alternates"
            if k:
                msg += '["{0}"]'.format(k)
            msg += " of {0}".format(script_class_name)
            e.args = (e.args[0] + msg,) + e.args[1:]
            raise
        return {"a": valid}
コード例 #3
0
class Rule(object):
    """ Pattern matching and response rule.

    Describes one method decorated by @rule. Parses
    the simplified regular expression strings, raising PatternError
    if there is an error. Can match the pattern and previous_pattern
    against tokenized input (a Target) and return a Match object.

    Public instance variables:
    pattern - the Pattern object to match against the current message
    previous - the Pattern object to match against the previous reply
    weight - the weight, given to @rule
    method - a reference to the decorated method
    rulename - modulename.classname.methodname, for error messages

    Public methods:
    match - given current message and reply history, return a Match
            object if the patterns match or None if they don't
    full set of comparison operators - to enable sorting first by weight then
            score of the two patterns
    """
    def __init__(self, raw_pattern, raw_previous, weight, alternates,
                 method, rulename):
        """ Create a new Rule object based on information supplied to the
        @rule decorator. Arguments:
        raw_pattern - simplified regular expression string supplied to @rule
        raw_previous - simplified regular expression string supplied to @rule
        weight -  weight supplied to @rule
        alternates - dictionary of variable names and values that can
                   be substituted in the patterns
        method - reference to method decorated by @rule
        rulename - modulename.classname.methodname, used to make better
                 error messages

        Raises PatternError, PatternVariableNotFoundError,
               PatternVariableValueError
        """
        try:
            previous = ""
            if not raw_pattern:
                raise PatternError("Empty string found")
            self.pattern = Pattern(raw_pattern, alternates)
            previous = "previous "
            self.previous = Pattern(raw_previous, alternates)
        except (TypeError, PatternError, PatternVariableValueError,
                PatternVariableNotFoundError) as e:
            msg = " in {0}pattern of {1}".format(previous, rulename)
            e.args = (e.args[0] + msg,) + e.args[1:]
            raise

        self.weight = weight
        self.method = method
        self.rulename = rulename

    def match(self, target, history, variables):
        """ Return a Match object if the targets match the patterns
        for this rule, or None if they don't.
        Arguments:
            target - a Target object for the user's message
            history - a deque object containing Targets for previous
                      replies
            variables - User and Bot variables for the PatternParser
                      to substitute into the patterns
        """
        m = self.pattern.match(target.normalized, variables)
        if m is None:
            return None
        mp = None
        reply_target = None

        if self.previous:
            if not history:
                return None
            reply_target = history[0]
            mp = self.previous.match(reply_target.normalized, variables)
            if mp is None:
                return None
        return Match(m, mp, target, reply_target)

    def __lt__(self, other):
        """ Full set of comparison operators. The weight passed to @rule
        is the most significant, followed by the complexity of the pattern
        and the complexity of the previous pattern.
        """
        return (self.weight < other.weight or
                (self.weight == other.weight and
                 self.pattern.score < other.pattern.score) or
                (self.weight == other.weight and
                 self.pattern.score == other.pattern.score and
                 self.previous.score < other.previous.score))

    def __eq__(self, other):
        return (self.weight == other.weight and
                self.pattern.score == other.pattern.score and
                self.previous.score == other.previous.score)

    def __gt__(self, other):
        return not (self == other or self < other)

    def __le__(self, other):
        return self < other or self == other

    def __ge__(self, other):
        return self > other or self == other

    def __ne__(self, other):
        return not self == other