Commits

Jonathan Eunice  committed ccbeca7

added prettyprint method and fmtfunc option

  • Participants
  • Parent commits 4ead8a1

Comments (0)

Files changed (5)

 Or if you'd like all properties except a few::
 
     show.props(x, omit='description,blurb')
+    
+Changing How Things Are Shown
+=============================
+
+By default, ``show`` uses Python's ``repr()`` function to format
+values. You may prefer some other kind of representation or formatting,
+however. For example, the ``pprint`` module pretty-prints data structures.
+You can set it to be the default formatter::
+
+    from pprint import pformat
+    show.set(fmtfunc=pformat)
+    
+    # NB pformat, not pprint!
+
+Or to configure ``pformat`` more precisely::
+
+    show.set(fmtfunc=lambda x: pformat(x, indent=4, width=120, depth=5))
+    
+Or you can set more complex pretty printing functions, using syntax
+highlighting and other transformations. As a convenience, ``show``
+provides a method that uses ``pygments`` and
+``pprint`` in concert to more attractively display text. Just::
+
+    show.prettyprint()
+    
+does the trick. It also takes ``indent``, ``depth``, and ``width`` options
+for ``pformat`` and the ``style`` (style name) option for ``pygments``.
+Some style names to try::
+
+    # monokai manni rrt perldoc borland colorful default
+    # murphy vs trac tango fruity autumn bw emacs vim pastie
+    # friendly native
 
 Showing What's Changed
 ======================
 
 ::
 
-    show.watch()
+    show.changed()
     
 will display the value of local variables. When invoked again, only those
-variables that have changed (since the last ``show.watch()`` in the same context)
+variables that have changed (since the last ``show.changed()`` in the same context)
 will be displayed. 
 
 You may ``omit`` some local variables if you like.
 By default, those starting with underscores (``_``) will be omitted, as
 will those containing functions, methods, builtins, and other parts Python
 program infrastructure. If you'd like to add those, or global variables into
-the mix, that's easily done:
+the mix, that's easily done::
 
-    show.watch(_private, MY_GLOBAL_VAR)
+    show.changed(_private, MY_GLOBAL_VAR)
     
 Will start watching those.
+
+**NB** ``changed()`` used to be called ``watch()``. The old ``watch()`` method
+will still work (it's just an alias to ``changed``), but in the future it will
+be going away.
     
 Interactive Limitations
 =======================
 Or if you'd like all properties except a few::
 
     show.props(x, omit='description,blurb')
+    
+Changing How Things Are Shown
+=============================
+
+By default, ``show`` uses Python's ``repr()`` function to format
+values. You may prefer some other kind of representation or formatting,
+however. For example, the ``pprint`` module pretty-prints data structures.
+You can set it to be the default formatter::
+
+    from pprint import pformat
+    show.set(fmtfunc=pformat)
+    
+    # NB pformat, not pprint!
+
+Or to configure ``pformat`` more precisely::
+
+    show.set(fmtfunc=lambda x: pformat(x, indent=4, width=120, depth=5))
+    
+Or you can set more complex pretty printing functions, using syntax
+highlighting and other transformations. As a convenience, ``show``
+provides a method that uses ``pygments`` and
+``pprint`` in concert to more attractively display text. Just::
+
+    show.prettyprint()
+    
+does the trick. It also takes ``indent``, ``depth``, and ``width`` options
+for ``pformat`` and the ``style`` (style name) option for ``pygments``.
+Some style names to try::
+
+    # monokai manni rrt perldoc borland colorful default
+    # murphy vs trac tango fruity autumn bw emacs vim pastie
+    # friendly native
 
 Showing What's Changed
 ======================
 
 ::
 
-    show.watch()
+    show.changed()
     
 will display the value of local variables. When invoked again, only those
-variables that have changed (since the last ``show.watch()`` in the same context)
+variables that have changed (since the last ``show.changed()`` in the same context)
 will be displayed. 
 
 You may ``omit`` some local variables if you like.
 By default, those starting with underscores (``_``) will be omitted, as
 will those containing functions, methods, builtins, and other parts Python
 program infrastructure. If you'd like to add those, or global variables into
-the mix, that's easily done:
+the mix, that's easily done::
 
-    show.watch(_private, MY_GLOBAL_VAR)
+    show.changed(_private, MY_GLOBAL_VAR)
     
 Will start watching those.
+
+**NB** ``changed()`` used to be called ``watch()``. The old ``watch()`` method
+will still work (it's just an alias to ``changed``), but in the future it will
+be going away.
     
 Interactive Limitations
 =======================
 
 setup(
     name='show',
-    version='0.60',
+    version='0.61',
     author='Jonathan Eunice',
     author_email='jonathan.eunice@gmail.com',
     description='Debug print statements, done right. E.g. show(x)',

File show/core.py

         retvalue=False,     # return the value printed?
         props=Transient,    # props desired to print (given at call time)
         omit=Transient,     # vars not to print (for show.locals)
+        fmtfunc=repr,       # formatting func used to format each value
     )
 
     def __init__(self, **kwargs):
         are not interpreted as format template characters when the composed string
         is eventually output by ``say``.
         """
-        return self.say.escape(repr(value))
+        return self.say.escape(self.opts.fmtfunc(value))
 
     def arg_format(self, name, value, caller):
         """
         if name.startswith(QUOTE_CHARS):
             ret = fmt(value, **{'_callframe': caller})
             return ret
-        else:                
+        else:
+            fvalue = self.value_repr(value)
             if isinstance(value, (list, dict, set, six.string_types)):  # weak test
                 length = len(value)
                 itemname = 'char' if isinstance(value, six.string_types) else 'item'
                 s_or_nothing = '' if length == 1 else 's'
-                fvalue = self.value_repr(value)
                 return "{0} ({1} {2}{3}): {4}".format(name, length, itemname, s_or_nothing, fvalue)
             else:
-                return "{0}: {1!r}".format(name, value)
+                return "{0}: {1}".format(name, fvalue)
 
     def arg_format_props(self, name, value, caller, ignore_double=True, ignore_funky=True):
         """
         if opts.retvalue:
             return retval
 
-    def watch(self, *args, **kwargs):
+    def changed(self, *args, **kwargs):
         """
         Show the local variables, then again only when changed.
         """
         retval = self.say(*locval, **kwargs)
         if opts.retvalue:
             return retval
+            
+    watch = changed
+    # to be removed soon
         
     def inout(self, func):
         """
             
         return echo_func
     
+    def prettyprint(self, mode='ansi', indent=4, width=120, depth=5, style='default'):
+        """
+        Convenience method to turn on pretty-printing. Mode can be text or ansi.
+        """
+        mode = mode.lower()
+        from pprint import pformat
+        pf = lambda x: pformat(x, indent=indent, width=width, depth=depth)
+        if mode == 'text':
+            self.set(fmtfunc=pf)
+        elif mode == 'ansi':
+            try:
+                from pygments import highlight
+                from pygments.lexers import PythonLexer
+                lexer = PythonLexer()
+                from pygments.formatters import Terminal256Formatter
+                formatter = Terminal256Formatter(style=style)
+                self.set(fmtfunc=lambda x: highlight(pf(x), lexer, formatter).strip())
+            except ImportError:
+                raise ImportWarning('install pygments for ANSI formatting; falling back to plain text')
+                self.set(fmtfunc=pf)
+            except Exception as e:
+                raise e
+        else:
+            raise ValueError("'{0}' is not a recognized pretty print mode").format(mode)
+
     # TODO: Give option for showing return value differently
     # TODO: Give this decorator standard show kwargs
     # TODO: Unifiy inout and retval function argument/return value decorators

File test/test_show.py

     out, err = capsys.readouterr()
     assert out == "f(a=12) -> 13\n"
     assert err == ""
+
+# Does not test interactive usage (under ipython, eg) in any automated fashion.
+# Nor does it test the formatted output through Pygments and pformat.