Allow providing a node stringify function to tree pformat

Allow providing a node to string function that will be activated
when the root node pformat routine needs to format a node into
a string (for viewing purposes); this allows for subclasses or
other users of nodes to provide there own function that they can
specialize as they see fit (without duplicating the pformat
routine itself).

To start use it to print out the node link target in the fake
in-memory filesystem when a link is encountered.

Change-Id: I33b8f1ec8d30d72ae35971e35f5edd84a9145db7
This commit is contained in:
Joshua Harlow
2015-03-23 16:15:38 -07:00
committed by Joshua Harlow
parent 179854e3ee
commit de68bc2d72
2 changed files with 21 additions and 7 deletions

View File

@@ -19,6 +19,8 @@ import contextlib
import copy import copy
import posixpath as pp import posixpath as pp
import six
from taskflow import exceptions as exc from taskflow import exceptions as exc
from taskflow.persistence import path_based from taskflow.persistence import path_based
from taskflow.types import tree from taskflow.types import tree
@@ -136,9 +138,16 @@ class FakeFilesystem(object):
raise ValueError("Can not delete '%s'" % self._root.item) raise ValueError("Can not delete '%s'" % self._root.item)
node.disassociate() node.disassociate()
@staticmethod
def _stringify_node(node):
if 'target' in node.metadata:
return "%s (link to %s)" % (node.item, node.metadata['target'])
else:
return six.text_type(node.item)
def pformat(self): def pformat(self):
"""Pretty format this in-memory filesystem.""" """Pretty format this in-memory filesystem."""
return self._root.pformat() return self._root.pformat(stringify_node=self._stringify_node)
def symlink(self, src_path, dest_path): def symlink(self, src_path, dest_path):
"""Link the destionation path to the source path.""" """Link the destionation path to the source path."""

View File

@@ -200,7 +200,7 @@ class Node(object):
# NOTE(harlowja): 0 is the right most index, len - 1 is the left most # NOTE(harlowja): 0 is the right most index, len - 1 is the left most
return self._children[index] return self._children[index]
def pformat(self): def pformat(self, stringify_node=None):
"""Recursively formats a node into a nice string representation. """Recursively formats a node into a nice string representation.
**Example**:: **Example**::
@@ -220,24 +220,29 @@ class Node(object):
|__Mobile |__Mobile
|__Mail |__Mail
""" """
def _inner_pformat(node, level): def _inner_pformat(node, level, stringify_node):
if level == 0: if level == 0:
yield six.text_type(node.item) yield stringify_node(node)
prefix = self.STARTING_PREFIX prefix = self.STARTING_PREFIX
else: else:
yield self.HORIZONTAL_CONN + six.text_type(node.item) yield self.HORIZONTAL_CONN + stringify_node(node)
prefix = self.EMPTY_SPACE_SEP * len(self.HORIZONTAL_CONN) prefix = self.EMPTY_SPACE_SEP * len(self.HORIZONTAL_CONN)
child_count = node.child_count() child_count = node.child_count()
for (i, child) in enumerate(node): for (i, child) in enumerate(node):
for (j, text) in enumerate(_inner_pformat(child, level + 1)): for (j, text) in enumerate(_inner_pformat(child,
level + 1,
stringify_node)):
if j == 0 or i + 1 < child_count: if j == 0 or i + 1 < child_count:
text = prefix + self.VERTICAL_CONN + text text = prefix + self.VERTICAL_CONN + text
else: else:
text = prefix + self.EMPTY_SPACE_SEP + text text = prefix + self.EMPTY_SPACE_SEP + text
yield text yield text
if stringify_node is None:
# Default to making a unicode string out of the nodes item...
stringify_node = lambda node: six.text_type(node.item)
expected_lines = self.child_count(only_direct=False) expected_lines = self.child_count(only_direct=False)
accumulator = six.StringIO() accumulator = six.StringIO()
for i, line in enumerate(_inner_pformat(self, 0)): for i, line in enumerate(_inner_pformat(self, 0, stringify_node)):
accumulator.write(line) accumulator.write(line)
if i < expected_lines: if i < expected_lines:
accumulator.write(self.LINE_SEP) accumulator.write(self.LINE_SEP)