Changeset 282
- Timestamp:
- 12/08/05 19:10:06 (3 years ago)
- Files:
-
- pycrash/trunk/crash/classmaker.py (added)
- pycrash/trunk/crash/component.py (modified) (1 diff)
- pycrash/trunk/crash/console.py (modified) (5 diffs)
- pycrash/trunk/crash/decorators.py (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
pycrash/trunk/crash/component.py
r281 r282 218 218 """ 219 219 return True 220 221 def get_implementors(self, interface): 222 """ Get all component classes that implement a particular interface as 223 a dictionary, with the class name as the key and the class itself as 224 the value. Does not instantiate the component. """ 225 return dict((c.__name__, c) for c in ComponentMeta._components \ 226 if hasattr(c, '_implements') and interface in c._implements) pycrash/trunk/crash/console.py
r280 r282 127 127 return out 128 128 129 __cwrap_re = re.compile(r'''(\n)|(\s+)|((?:\^[N0-7BU]|\S)+\b[^ ^\w]*)''')130 def cwraptext( text, width = termwidth(), subsequent_indent = ''):129 __cwrap_re = re.compile(r'''(\n)|(\s+)|((?:\^[N0-7BU]|\S)+\b[^\n^\w]*)''') 130 def cwraptext(rtext, width = termwidth(), subsequent_indent = ''): 131 131 """ Wrap multi-line text to width (defaults to termwidth()) """ 132 132 out = [] 133 tokens = [t.group(0) for t in __cwrap_re.finditer(text)] + [' ' * width] 134 line = tokens.pop(0) 135 first_line = 1 136 137 138 def add_line(line, first_line): 139 if clen(line.rstrip()) > width: 140 tokens.insert(0, csplice(line, width)) 141 line = csplice(line, 0, width) 142 out.append((not first_line and subsequent_indent or '') + line.rstrip()) 143 first_line = 0 144 if not out[-1]: 145 out.pop() 146 return first_line 147 148 while tokens: 149 if clen(line) + clen(tokens[0].rstrip()) > width: 150 first_line = add_line(line, first_line) 151 line = tokens.pop(0) 133 for text in rtext.splitlines(): 134 tokens = [t.group(0) for t in __cwrap_re.finditer(text)] + [' ' * width] 135 line = tokens.pop(0) 136 first_line = 1 137 138 def add_line(line, first_line): 139 if clen(line.rstrip()) > width: 140 tokens.insert(0, csplice(line, width)) 141 line = csplice(line, 0, width) 142 out.append((not first_line and subsequent_indent or '') + line.rstrip()) 143 first_line = 0 144 if not out[-1]: 145 out.pop() 146 return first_line 147 148 if tokens: 149 while tokens: 150 if clen(line) + clen(tokens[0].rstrip()) > width: 151 first_line = add_line(line, first_line) 152 line = tokens.pop(0) 153 else: 154 line += tokens.pop(0) 155 if line: 156 add_line(line, first_line) 152 157 else: 153 line += tokens.pop(0) 154 if line: 155 add_line(line, first_line) 158 out.append('') 156 159 return out 157 160 … … 176 179 return out.rstrip() 177 180 178 def print_table(table, header = None, sep = ' ', auto_format = ['^B^U', '^6', '^B^6'] ):181 def print_table(table, header = None, sep = ' ', auto_format = ['^B^U', '^6', '^B^6'], expand_to_fit = 1): 179 182 """Print a list of lists as a table, so that columns line up nicely. 180 183 header, if specified, will be printed as the first row. sep is the … … 184 187 row. The first element is the header colour, subsequent elements are 185 188 for alternating rows. eg. [ '^B', '^1', '^2' ] 189 190 expand_to_fit signifies whether print_table should expand the table to the 191 width of the terminal. 186 192 187 Note: print_table supports an additional formatting code, ^R, which 188 corresponds to the colour formatting of the current table row. """ 193 Note: print_table supports the ^R formatting code, in addition to those 194 supported by cprint, which corresponds to the colour formatting of the 195 current table row. """ 189 196 def ctlen(s): 190 197 return clen(s.replace('^R', '')) 191 198 199 seplen = len(sep) 192 200 # Find column scale factor 193 201 if header: … … 195 203 rows, cols = len(table), len(table[0]) 196 204 colwidths = [0] * cols 197 #minwidth = termwidth() / cols198 205 for i in range(0, cols): 199 206 colwidths[i] = max(map(lambda c: max(map(ctlen, c[i].splitlines())), table)) 200 207 if i < cols - 1: 201 colwidths[i] += len(sep) 202 twidth = sum(colwidths) 203 scale = float(termwidth() - 1) / float(twidth) 204 colwidths = [int(float(x) * scale) for x in colwidths] 208 colwidths[i] += seplen 209 # Scale columns if total width is less than the terminal width, or user requested 210 if termwidth() < sum(colwidths) or expand_to_fit: 211 scale = float(termwidth() - 1) / float(sum(colwidths)) 212 colwidths = [int(float(x) * scale) for x in colwidths] 213 mincol = min(colwidths) 214 for i, col in enumerate(colwidths): 215 if col == mincol: 216 colwidths[0] += termwidth() - sum(colwidths) 217 205 218 auto_format = auto_format[:] 206 219 … … 218 231 else: 219 232 fmt = auto_format[rowalt % len(auto_format)] 220 xrow = [cwraptext(col.replace('^R', fmt), colwidths[i]) for i, col in enumerate(row)] 233 # Perform wrapping 234 xrow = [cwraptext(col.replace('^R', fmt), colwidths[i] - (i < cols - 1 and seplen or 0)) for i, col in enumerate(row)] 235 # Pad column rows out to the maximum of all columns 236 maxrows = max(map(len, xrow)) 237 for col in xrow: 238 col += [''] * (maxrows - len(col)) 221 239 realrows = max(map(len, xrow)) 222 xrow = [x + [''] * (realrows - len(x)) for x in xrow]240 # Emit 223 241 for i in range(0, realrows): 224 242 cwrite(sys.stdout, fmt) 225 243 for j, col in enumerate(xrow): 226 cwrite(sys.stdout, col[i].replace('^R', fmt) + sep * (colwidths[j] - ctlen(col[i]))) 227 if j < cols - 1: 244 slen = j < cols - 1 and seplen or 0 245 cwrite(sys.stdout, col[i] + ' ' * (colwidths[j] - ctlen(col[i]) - slen)) 246 if slen: 228 247 cwrite(sys.stdout, sep) 229 248 cwrite(sys.stdout, '^N\n') pycrash/trunk/crash/decorators.py
r279 r282 69 69 #import inspect 70 70 #caller = inspect.getouterframes(inspect.currentframe())[1][3] 71 return DelayedAbstractException(NotImplementedError( func.__name__ + ' must be implemented in subclass'), func.__doc__)71 return DelayedAbstractException(NotImplementedError('%s() must be implemented in subclass' % func.__name__), func.__doc__) 72 72 73 73 # Based on code from http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/438819 … … 76 76 make all members 'private' (prefixed by an underscore)""" 77 77 def outer(func): 78 def inner( *args, **kwargs):78 def inner(self, *args, **kwargs): 79 79 A = {} 80 self = args[0]81 arg s = args[1:]80 args = list(args) 81 argc = len(args) 82 82 for i, arg in enumerate(func.func_code.co_varnames[1:func.func_code.co_argcount]): 83 if i < len(args): 84 A[arg] = args[i] 83 if len(args): 84 A[arg] = args[0] 85 del args[0] 85 86 elif kwargs.has_key(arg): 86 87 A[arg] = kwargs[arg] 88 del kwargs[arg] 87 89 else: 88 90 the_default_arg = i - func.func_code.co_argcount + 1 … … 90 92 for name, value in A.items(): 91 93 setattr(self, (private and '_' or '') + name, value) 94 # Do some basic sanity checking on any remaining arguments 95 if args: 96 raise TypeError("%s() takes at most %i arguments (%i given)" % (func.__name__, func.func_code.co_argcount, argc)) 97 if kwargs: 98 raise TypeError("%s() got an unexpected keyword argument '%s'" % (func.__name__, kwargs.keys()[0])) 92 99 return func(self, **A) 93 100 inner.__doc__ = func.__doc__
