Source code for alf.utils.pretty_print

# Copyright (c) 2023 Horizon Robotics and ALF Contributors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from io import StringIO
import pprint
try:
    from pygments import highlight
    from pygments.formatters import Terminal256Formatter
    from pygments.lexers import PythonLexer
    _py_color = True
except:
    # fallback to no python syntax highlighting
    _py_color = False


[docs]class PrettyPrinter(pprint.PrettyPrinter): """Copied from https://stackoverflow.com/questions/30062384/pretty-print-namedtuple """
[docs] def format_namedtuple(self, object, stream, indent, allowance, context, level): # Code almost equal to _format_dict, see pprint code write = stream.write write(object.__class__.__name__ + '(') object_dict = object._asdict() length = len(object_dict) if length: # We first try to print inline, and if it is too large then we print it on multiple lines inline_stream = StringIO() self.format_namedtuple_items( object_dict.items(), inline_stream, indent, allowance + 1, context, level, inline=True) max_width = self._width - indent - allowance if len(inline_stream.getvalue()) > max_width: self.format_namedtuple_items( object_dict.items(), stream, indent, allowance + 1, context, level, inline=False) else: stream.write(inline_stream.getvalue()) write(')')
[docs] def format_namedtuple_items(self, items, stream, indent, allowance, context, level, inline=False): # Code almost equal to _format_dict_items, see pprint code indent += self._indent_per_level write = stream.write last_index = len(items) - 1 if inline: delimnl = ', ' else: delimnl = ',\n' + ' ' * indent write('\n' + ' ' * indent) for i, (key, ent) in enumerate(items): last = i == last_index write(key + '=') self._format(ent, stream, indent + len(key) + 2, allowance if last else 1, context, level) if not last: write(delimnl)
def _format(self, object, stream, indent, allowance, context, level): # We dynamically add the types of our namedtuple and namedtuple like # classes to the _dispatch object of pprint that maps classes to # formatting methods # We use a simple criteria (_asdict method) that allows us to use the # same formatting on other classes but a more precise one is possible if (hasattr(object, '_asdict') and type(object).__repr__ not in self._dispatch): self._dispatch[type(object). __repr__] = PrettyPrinter.format_namedtuple super()._format(object, stream, indent, allowance, context, level)
pp = PrettyPrinter(indent=2)
[docs]def pformat_pycolor(obj): if _py_color: return highlight( pp.pformat(obj), PythonLexer(), Terminal256Formatter()) return pp.pformat(obj)