diff --git a/libtaskotron/directives/python_directive.py b/libtaskotron/directives/python_directive.py
--- a/libtaskotron/directives/python_directive.py
+++ b/libtaskotron/directives/python_directive.py
@@ -66,6 +66,11 @@
 
         output = task_method(**kwargs)
 
+        if output is not None and not isinstance(output, basestring):
+            raise TaskotronDirectiveError(
+                "Callable task method must return string or None, actual "
+                "returned type: %s" % type(output))
+
         return output
 
     def load_pyfile(self, filename):
diff --git a/libtaskotron/runner.py b/libtaskotron/runner.py
--- a/libtaskotron/runner.py
+++ b/libtaskotron/runner.py
@@ -198,8 +198,6 @@
     task_runner = Runner(task_data, arg_data)
     task_runner.run()
 
-    for output in task_runner.working_data:
-        if python_utils.sequence(task_runner.working_data[output], basestring):
-            log.info("\n" + "\n".join(task_runner.working_data[output]))
-        else:
-            log.info("\n" + task_runner.working_data[output])
+    log.info('Check execution finished. Showing stored variables:')
+    for name, value in task_runner.working_data.items():
+        log.info("${%s}:\n%s" % (name, value))
diff --git a/testing/test_python_directive.py b/testing/test_python_directive.py
--- a/testing/test_python_directive.py
+++ b/testing/test_python_directive.py
@@ -1,4 +1,5 @@
 from libtaskotron.directives import python_directive
+from libtaskotron.exceptions import TaskotronDirectiveError
 from dingus import Dingus
 import os
 import imp
@@ -50,7 +51,7 @@
         ref_methodname = 'bar'
         ref_kwargs = {'baz': 'why', 'blah': 2}
 
-        stub_getattr = Dingus()
+        stub_getattr = Dingus(return_value=lambda baz, blah: "str")
 
         test_directive = python_directive.PythonDirective()
         monkeypatch.setattr(test_directive, '_do_getattr', stub_getattr)
@@ -65,15 +66,95 @@
         ref_methodname = 'bar'
         ref_kwargs = {'baz': 'why', 'blah': 2}
 
-        stub_getattr = Dingus()
+        stub_task = Dingus(return_value="str")
+        stub_getattr = Dingus(return_value=stub_task)
 
         test_directive = python_directive.PythonDirective()
         monkeypatch.setattr(test_directive, '_do_getattr', stub_getattr)
 
         test_directive.execute(ref_modulename, ref_methodname, ref_kwargs)
 
-        assert (stub_getattr.calls()[1].name, stub_getattr.calls()[1].args,
-                stub_getattr.calls()[1].kwargs) == ('()', (), ref_kwargs)
+        assert (stub_task.calls()[0].name, stub_task.calls()[0].args,
+                stub_task.calls()[0].kwargs) == ('()', (), ref_kwargs)
+
+
+class TestPyfileOutputException(object):
+
+    def test_task_doesnt_rise_on_unicode_str(self, monkeypatch):
+        ref_modulename = 'foo'
+        ref_methodname = 'bar'
+        ref_kwargs = {'baz': 'why', 'blah': 2}
+
+        stub_task = Dingus(return_value=u"unicode")
+        stub_getattr = Dingus(return_value=stub_task)
+
+        test_directive = python_directive.PythonDirective()
+        monkeypatch.setattr(test_directive, '_do_getattr', stub_getattr)
+
+        test_directive.execute(ref_modulename, ref_methodname, ref_kwargs)
+
+        assert (stub_task.calls()[0].name, stub_task.calls()[0].args,
+                stub_task.calls()[0].kwargs) == ('()', (), ref_kwargs)
+
+    def test_task_doesnt_rise_on_empty_str(self, monkeypatch):
+        ref_modulename = 'foo'
+        ref_methodname = 'bar'
+        ref_kwargs = {'baz': 'why', 'blah': 2}
+
+        stub_task = Dingus(return_value="")
+        stub_getattr = Dingus(return_value=stub_task)
+
+        test_directive = python_directive.PythonDirective()
+        monkeypatch.setattr(test_directive, '_do_getattr', stub_getattr)
+
+        test_directive.execute(ref_modulename, ref_methodname, ref_kwargs)
+
+        assert (stub_task.calls()[0].name, stub_task.calls()[0].args,
+                stub_task.calls()[0].kwargs) == ('()', (), ref_kwargs)
+
+    def test_task_doesnt_rise_on_none(self, monkeypatch):
+        ref_modulename = 'foo'
+        ref_methodname = 'bar'
+        ref_kwargs = {'baz': 'why', 'blah': 2}
+
+        stub_task = Dingus(return_value=None)
+        stub_getattr = Dingus(return_value=stub_task)
+
+        test_directive = python_directive.PythonDirective()
+        monkeypatch.setattr(test_directive, '_do_getattr', stub_getattr)
+
+        test_directive.execute(ref_modulename, ref_methodname, ref_kwargs)
+
+        assert (stub_task.calls()[0].name, stub_task.calls()[0].args,
+                stub_task.calls()[0].kwargs) == ('()', (), ref_kwargs)
+
+    def test_task_rises_on_empty_list(self, monkeypatch):
+        ref_modulename = 'foo'
+        ref_methodname = 'bar'
+        ref_kwargs = {'baz': 'why', 'blah': 2}
+
+        stub_task = Dingus(return_value=[])
+        stub_getattr = Dingus(return_value=stub_task)
+
+        test_directive = python_directive.PythonDirective()
+        monkeypatch.setattr(test_directive, '_do_getattr', stub_getattr)
+
+        with pytest.raises(TaskotronDirectiveError):
+            test_directive.execute(ref_modulename, ref_methodname, ref_kwargs)
+
+    def test_task_rises_on_wrong_type(self, monkeypatch):
+        ref_modulename = 'foo'
+        ref_methodname = 'bar'
+        ref_kwargs = {'baz': 'why', 'blah': 2}
+
+        stub_task = Dingus(return_value={'han': 'shot', 'first': True})
+        stub_getattr = Dingus(return_value=stub_task)
+
+        test_directive = python_directive.PythonDirective()
+        monkeypatch.setattr(test_directive, '_do_getattr', stub_getattr)
+
+        with pytest.raises(TaskotronDirectiveError):
+            test_directive.execute(ref_modulename, ref_methodname, ref_kwargs)
 
 
 class TestProcess(object):

