def human_readable_lines(self, wrap=80, label=""): """A pretty human readable representation of the object. Args: wrap: maximum number of characters per line. 0 or negative wrap means no limit. Should be chosen long enough to comfortably fit formatted data; otherwise it is simply ignored and output may look funny. label: a label prefix. Returns: a list of line strings of at most |wrap| characters each. """ # A "\n" becomes ["", ""] which magically starts a new line when we call # append_lines() on it. Things like "\n-----\n" work, too. delimiter = (print_util.wrap_lines(self.print_delimiter, wrap=wrap)) lines = [] # Component count. Needed so we can print "<no components>" when none # are found. count = 0 # Whether the next component should start on a new line. Set to true # when the previous component was multiline. For example, a mix of short # and long components with a ", " delimiter is thus printed as # short1, short2, short3, # myextremelylongcomponentth # atspansmultiplelines # short4, short5 newline = False if label: lines += print_util.wrap_lines(label + ":", wrap) # If the delimiter is multiline, then output looks prettier if the # label is also on a separate line. if len(delimiter) > 1: newline = True elif len(lines[-1]) < wrap: # Else add a whitespace so we get "label: value" lines[-1] += " " indent = 2 for key, value in self.iteritems(): if value is None: continue label = str(key) if self.print_labels else "" print_component = value.human_readable_lines(wrap=wrap-indent, label=label) if not print_component: continue if count: print_util.append_lines(delimiter, wrap, lines) count += 1 # Make multiline components a separate block on a new line, unless # we already are on a new line. if (newline or len(print_component) > 1) and lines and lines[-1]: lines += print_component else: print_util.append_lines(print_component, wrap, lines) newline = len(print_component) > 1 if not count: print_util.append_lines(["<no components>"], wrap, lines) # Indent everything apart from the first line. return [lines[0]] + [" " + x for x in lines[1:]]
def test_append_lines_honours_wrap(self): buf = ["hello"] lines = ["beautiful", "world"] # "hellobeautiful" is more than 10 characters long print_util.append_lines(lines, 10, buf) self.assertEqual(["hello", "beautiful", "world"], buf)