Beispiel #1
0
class question(knowledge_base.knowledge_entity_list):
    r'''
        This represents one question in a question_base.  It takes care of
        lookup parameters and caching and delegates the work of actually
        asking the user a question to the user_question object by calling its
        'ask' method passing the format parameters.
    '''
    not_found = unique.unique('question.not_found')

    def __init__(self, name, params, answer_param, user_question):
        super(question, self).__init__(name)
        self.params = tuple(params)
        self.answer_param = answer_param
        try:
            self.answer_param_position = list(params).index(answer_param)
        except ValueError:
            raise ValueError("question %s: answer parameter, %s, "
                             "not in params list: %s" % (answer_param, params))
        self.input_param_positions = \
            tuple(filter(lambda i: i != self.answer_param_position,
                         range(len(self.params))))
        self.user_question = user_question
        self.cache = {}

    def __repr__(self):
        return "<question %s(%s): $%s = %s>" % \
               (self.name, ', '.join('$' + p for p in self.params),
                self.answer_param, repr(self.user_question))

    def set_knowledge_base(self, question_base):
        self.knowledge_base = question_base
        self.user_question.set_question_base(question_base)

    def lookup(self, bindings, pat_context, patterns):
        input_params = tuple(
            (self.params[i], unicode(patterns[i].as_data(pat_context)))
            for i in self.input_param_positions)
        format_params = dict(input_params)
        ans = self.cache.get(input_params, self.not_found)
        if ans is self.not_found:
            ans = self.cache[input_params] = \
                self.user_question.ask(format_params)

        def gen():
            mark = bindings.mark(True)
            end_done = False
            try:
                if patterns[self.answer_param_position] \
                       .match_data(bindings, pat_context, ans):
                    bindings.end_save_all_undo()
                    end_done = True
                    yield
            finally:
                if not end_done: bindings.end_save_all_undo()
                bindings.undo_to_mark(mark)

        return contextlib.closing(gen())

    def reset(self):
        self.cache.clear()
Beispiel #2
0
        $_ignored
        >>> A_context.bind('_bogus', A_context, 567)
        False
        >>> A_context.lookup_data('_bogus')
        Traceback (most recent call last):
            ...
        KeyError: '$_bogus not bound'
        >>> A_context.lookup_data('_bogus', True)
        '$_bogus'
"""

import sys

from pyke import pattern, unique

_Not_found = unique.unique('Not_found')

# Set to a sequence (or frozenset) of variable names to trace their bindings:
debug = ()

class simple_context(object):
    def __init__(self):
        self.bindings = {}
        self.undo_list = []
        self.save_all_undo_count = 0

    def dump(self):
        for var_name in sorted(self.bindings.keys()):
            print("%s: %s" % (var_name, repr(self.lookup_data(var_name, True))))

    def bind(self, var_name, var_context, val, val_context = None):
Beispiel #3
0
        $_ignored
        >>> A_context.bind('_bogus', A_context, 567)
        False
        >>> A_context.lookup_data('_bogus')
        Traceback (most recent call last):
            ...
        KeyError: '$_bogus not bound'
        >>> A_context.lookup_data('_bogus', True)
        '$_bogus'
"""

import sys

from pyke import pattern, unique

_Not_found = unique.unique('Not_found')

# Set to a sequence (or frozenset) of variable names to trace their bindings:
debug = ()

class simple_context(object):
    def __init__(self):
        self.bindings = {}
        self.undo_list = []
        self.save_all_undo_count = 0

    def dump(self):
        for var_name in sorted(self.bindings.iterkeys()):
            print "%s: %s" % (var_name, repr(self.lookup_data(var_name, True)))

    def bind(self, var_name, var_context, val, val_context = None):
Beispiel #4
0
class tracked_object(object, metaclass=metaclass_option1):
    r'''
        All classes to be tracked by an object base would be derived from this
        one:
    
        >>> class foo(tracked_object):
        ...     def __init__(self, arg):
        ...         super(foo, self).__init__()
        ...         print("foo.__init__:", arg)
        ...         self.x = arg    # should be ignored
        ... # doctest: +NORMALIZE_WHITESPACE
        metaclass: name foo , bases (<class 'experimental.metaclass.tracked_object'>,) ,
        dict keys ('__init__', '__module__')
    
    
        And we can keep deriving classes:
    
        >>> class bar(foo):
        ...     def __init__(self, arg1, arg2):
        ...         super(bar, self).__init__(arg1)
        ...         print("bar.__init__:", arg1, arg2)
        ...         self.y = arg2    # should be ignored
        ... # doctest: +NORMALIZE_WHITESPACE
        metaclass: name bar , bases (<class 'experimental.metaclass.foo'>,) ,
        dict keys ('__init__', '__module__')
    
    
        We can't do the next step directly in the class definition because the
        knowledge_engine.engine hasn't been created yet and so the object
        bases don't exist at that point in time.
    
        So this simulates adding the knowledge_base to the class later, after
        the knowledge_engine.engine and object bases have been created.
    
        >>> foo.knowledge_base = 'foo base'
        >>> bar.knowledge_base = 'bar base'
    
    
        And now we create some instances (shouldn't see any attribute change
        notifications here!):
    
        >>> f = foo(44)             # doctest: +NORMALIZE_WHITESPACE +ELLIPSIS
        tracked_object.__setattr__ called on object
          <experimental.metaclass.foo object at 0x...>
          with property _ignore_setattr and value True
        tracked_object.__setattr__ called on object
          <experimental.metaclass.foo object at 0x...>
          with property knowledgebase and value None
        foo.__init__: 44
        tracked_object.__setattr__ called on object
          <experimental.metaclass.foo object at 0x...>
          with property x and value 44
        add instance <experimental.metaclass.foo object at 0x...> to foo base
        >>> b = bar(55, 66)         # doctest: +NORMALIZE_WHITESPACE +ELLIPSIS
        tracked_object.__setattr__ called on object
          <experimental.metaclass.bar object at 0x...>
          with property _ignore_setattr and value True
        tracked_object.__setattr__ called on object
          <experimental.metaclass.bar object at 0x...>
          with property knowledgebase and value None
        foo.__init__: 55
        tracked_object.__setattr__ called on object
          <experimental.metaclass.bar object at 0x...>
          with property x and value 55
        bar.__init__: 55 66
        tracked_object.__setattr__ called on object
          <experimental.metaclass.bar object at 0x...>
          with property y and value 66
        add instance <experimental.metaclass.bar object at 0x...> to bar base
    
    
        And modify some attributes:
    
        >>> f.x = 'y'          # doctest: +NORMALIZE_WHITESPACE +ELLIPSIS
        tracked_object.__setattr__ called on object
          <experimental.metaclass.foo object at 0x...>
          with property x and value y
        tracked_object.__setattr__: notify foo base of attribute change:
          (<experimental.metaclass.foo object at 0x...>, x, y)
        >>> b.y = 'z'          # doctest: +NORMALIZE_WHITESPACE +ELLIPSIS
        tracked_object.__setattr__ called on object
          <experimental.metaclass.bar object at 0x...>
          with property y and value z
        tracked_object.__setattr__: notify bar base of attribute change:
          (<experimental.metaclass.bar object at 0x...>, y, z)
        >>> b.y = 'z' # should be ignored
        ...    # doctest: +NORMALIZE_WHITESPACE +ELLIPSIS
        tracked_object.__setattr__ called on object
          <experimental.metaclass.bar object at 0x...>
          with property y and value z
        >>> b.z = "wasn't set" # doctest: +NORMALIZE_WHITESPACE +ELLIPSIS
        tracked_object.__setattr__ called on object
          <experimental.metaclass.bar object at 0x...>
          with property z and value wasn't set
        tracked_object.__setattr__: notify bar base of attribute change:
          (<experimental.metaclass.bar object at 0x...>, z, wasn't set)
    
    '''
    _not_bound = unique('_not_bound') # a value that should != any other value!
    def __init__(self):
        self._ignore_setattr = True
        self.knowledgebase = None
        
    def __setattr__(self, attr, value):
        # This gets called when any attribute is changed.  We would need to
        # figure out how to ignore attribute setting by the __init__
        # function...
        #
        # Also the check to see if the attribute has actually changed by doing
        # a '!=' check could theoretically lead to problems.  For example this
        # would fail to change the attribute to another value that wasn't
        # identical to the first, but '==' to it: for example, 4 and 4.0.
        print("tracked_object.__setattr__ called on object %s with property %s and value %s" % (self, attr, value))
        if getattr(self, attr, self._not_bound) != value:
            super(tracked_object, self).__setattr__(attr, value)
            if not hasattr(self, '_ignore_setattr'):
                print("tracked_object.__setattr__: notify", self.knowledge_base, \
                      "of attribute change: (%s, %s, %s)" % (self, attr, value))