]> hydra-www.ietfng.org Git - dyna2/commitdiff
minor cleanup.
authorTim Vieira <tim.f.vieira@gmail.com>
Sat, 13 Jul 2013 15:24:26 +0000 (11:24 -0400)
committerTim Vieira <tim.f.vieira@gmail.com>
Sat, 13 Jul 2013 15:24:26 +0000 (11:24 -0400)
src/Dyna/Backend/Python/errors.py
src/Dyna/Backend/Python/interpreter.py
src/Dyna/Backend/Python/term.py

index 424b24b921a21f766eec05281b5bbe5a60eb5d7e..dfc5f9b5b05d946e2aa0698de04765bdac682510 100644 (file)
@@ -64,5 +64,61 @@ def show_traceback(einfo=None):
     h(etype, evalue, tb)
 
 
-def notimplemented(*_,**__):
-    raise NotImplementedError
+def rule_error_context():
+    """
+    Inspect the stack frame to extract local variable bindings of an update
+    handler, rule initializer or backward chaining routine.
+
+    >>> def f(x):
+    ...     y = 3
+    ...     return g(x)
+
+    >>> def g(x):
+    ...    return _(x)
+
+    >>> def _(x):             # target frame
+    ...    y = x + 1
+    ...    z = 3 * 4
+    ...    errorizer()
+
+    >>> def errorizer():
+    ...    a = 1
+    ...    b = 0
+    ...    c = a / b          # divide by zero error.
+    ...    d = 3              # will be undefined, along with c
+    ...    return 10
+
+    >>> try:
+    ...     print f(3)
+    ... except ZeroDivisionError:
+    ...     print rule_error_context()
+    {'y': 4, 'x': 3, 'z': 12}
+
+    """
+
+    # Move to the frame where the exception occurred, which is often not the
+    # same frame where the exception was caught.
+    tb = sys.exc_info()[2]
+    if tb is not None:
+        while 1:
+            if not tb.tb_next:
+                break
+            tb = tb.tb_next
+        f = tb.tb_frame
+    else:                             # no exception occurred
+        f = sys._getframe()
+
+    # get the stack frames
+    stack = []
+    while f:
+        stack.append(f)
+        f = f.f_back
+
+    rule_frame = None
+    for frame in stack:
+        if frame.f_code.co_name == '_':   # find frame which looks like an update handler (it's name is at least '_')
+            rule_frame = frame
+
+    if rule_frame is not None:
+        return dict(rule_frame.f_locals)
+    return {}
index 9a6a70214f31b8d437b2819eec6e4774db01c8ca..d61575c1bfa9f4b1dfe37b9f33ed68152a1a2556 100644 (file)
@@ -86,52 +86,10 @@ from utils import ip, red, green, blue, magenta, yellow, parse_attrs, \
 
 from prioritydict import prioritydict
 from config import dotdynadir
-from errors import crash_handler, AggregatorError, DynaCompilerError
+from errors import crash_handler, rule_error_context, AggregatorError, DynaCompilerError
 from stdlib import todyna
 
 
-def rule_error_context():
-    # Move to the frame where the exception occurred, which is often not the
-    # same frame where the exception was caught.
-    tb = sys.exc_info()[2]
-    if tb is not None:
-        while 1:
-            if not tb.tb_next:
-                break
-            tb = tb.tb_next
-        f = tb.tb_frame
-    else:                             # no exception occurred
-        f = sys._getframe()
-
-    # get the stack frames
-    stack = []
-    while f:
-        stack.append(f)
-        f = f.f_back
-
-    rule_frame = None
-    for frame in stack:
-        if frame.f_code.co_name == '_':   # find frame which looks like an update handler (it's name is at least '_')
-            rule_frame = frame
-
-            if False:
-                print 'Frame %s in %s at line %s' % (frame.f_code.co_name, frame.f_code.co_filename, frame.f_lineno)
-                for key, value in frame.f_locals.iteritems():
-                    print '%20s = %r' % (key, value)
-                print '\n'
-
-    if rule_frame is not None:
-        return dict(rule_frame.f_locals.items())
-    return {}
-
-
-def render_rule_context(rule, ctx, indent=''):
-    # TODO: highlight expression which caused the error.
-    from post.trace import Crux
-    c = Crux(head=None, rule=rule, body=None, vs = ctx)
-    return '\n'.join(indent + line for line in c.format())
-
-
 class Rule(object):
 
     def __init__(self, index):
@@ -160,6 +118,13 @@ class Rule(object):
     def __repr__(self):
         return 'Rule(%s, %r)' % (self.index, self.src)
 
+    def render_ctx(self, ctx, indent=''):
+        # TODO: highlight expression which caused the error.
+        from post.trace import Crux
+        c = Crux(head=None, rule=self, body=None, vs = ctx)
+        return '\n'.join(indent + line for line in c.format())
+
+
 
 # TODO: yuck, hopefully temporary measure to support pickling the Interpreter's
 # state
@@ -306,7 +271,7 @@ class Interpreter(object):
                     print >> out, '      %s' % (e)
                     print >> out
 
-                    print >> out, render_rule_context(r, e.exception_frame, indent='      ')
+                    print >> out, r.render_ctx(e.exception_frame, indent='      ')
                     print >> out
 
         # uninitialized rules
@@ -318,7 +283,7 @@ class Interpreter(object):
                 rule = self.rules[r]
                 print >> out, '   ', rule.src
                 print >> out, '  due to `%s`' % e
-                print >> out, render_rule_context(rule, e.exception_frame, indent='    ')
+                print >> out, rule.render_ctx(e.exception_frame, indent='    ')
                 print >> out
 
         print >> out
@@ -430,7 +395,7 @@ class Interpreter(object):
                 item.value = now
                 continue
 
-            except (ZeroDivisionError, TypeError, KeyboardInterrupt, NotImplementedError) as e:
+            except (ZeroDivisionError, TypeError, KeyboardInterrupt) as e:
                 error[item] = (None, [(e, None)])
 
                 now = self.build('$error/0')   # XXX: should go an agenda or run delete?
index 3ac67fdcd42696f21306e2b923e5e01379c5613b..ff80a460ba881e59e95e24082e29867dbadfc271 100644 (file)
@@ -1,4 +1,3 @@
-from errors import notimplemented
 from utils import _repr, true, false
 from aggregator import NoAggregator