#!/usr/bin/env python """ This file shows how you can define a custom stringifier for PuDB. A stringifier is a function that is called on the variables in the namespace for display in the variables list. The default is type()*, as this is fast and cannot fail. PuDB also includes built-in options for using str() and repr(). Note that str() and repr() will be slower than type(), which is especially noticable when you have many variables, or some of your variables have very large string/repr representations. Also note that if you just want to change the type for one or two variables, you can do that by selecting the variable in the variables list and pressing Enter, or by pressing t, s, or r. To define a custom stringifier, create a file like this one with a function called pudb_stringifier() at the module level. pudb_stringifier(obj) should return a string value for an object (note that str() will always be called on the result). Note that the file will be execfile'd. Then, go to the PuDB preferences window (type Ctrl-p inside of PuDB), and add the path to the file in the "Custom" field under the "Variable Stringifier" heading. The example in this file returns the string value, unless it take more than 500 ms (1 second in Python 2.5-) to compute, in which case it falls back to the type. TIP: Run "python -m pudb.run example-stringifier.py and set this file to be your stringifier in the settings to see how it works. You can use custom stringifiers to do all sorts of things: callbacks, custom views on variables of interest without having to use a watch variable or the expanded view, etc. * - Actually, the default is a mix between type() and str(). str() is used for a handful of "safe" types for which it is guaranteed to be fast and not to fail. """ import time import signal import sys import math class TimeOutError(Exception): pass def timeout(signum, frame, time): raise TimeOutError("Timed out after %d seconds" % time) def run_with_timeout(code, time, globals=None): """ Evaluate ``code``, timing out after ``time`` seconds. In Python 2.5 and lower, ``time`` is rounded up to the nearest integer. The return value is whatever ``code`` returns. """ # Set the signal handler and a ``time``-second alarm signal.signal(signal.SIGALRM, lambda s, f: timeout(s, f, time)) signal.setitimer(signal.ITIMER_REAL, time) r = eval(code, globals) signal.alarm(0) # Disable the alarm return r def pudb_stringifier(obj): """ This is the custom stringifier. It returns str(obj), unless it take more than a second to compute, in which case it falls back to type(obj). """ try: return run_with_timeout("str(obj)", 0.5, {'obj':obj}) except TimeOutError: return (type(obj), "(str too slow to compute)") # Example usage class FastString(object): def __str__(self): return "This was fast to compute." class SlowString(object): def __str__(self): time.sleep(10) # Return the string value after ten seconds return "This was slow to compute." fast = FastString() slow = SlowString() # If you are running this in PuDB, set this file as your custom stringifier in # the prefs (Ctrl-p) and run to here. Notice how fast shows the string value, # but slow shows the type, as the string value takes too long to compute.