Ticket #11834: 11834--2011-05-12.patch

File 11834--2011-05-12.patch, 7.7 KB (added by Thomas Güttler, 13 years ago)

patch which applies to 1.3.x SVN

  • django/views/debug.py

     
    5959    html = reporter.get_traceback_html()
    6060    return HttpResponseServerError(html, mimetype='text/html')
    6161
     62def get_traceback_color_scheme():
     63    """
     64    Use settings.TRACEBACK_COLOR_SCHEME to customize traceback colors.
     65    Format: 'prefix.part': (bg color, wrapper bg color, text color, show details),
     66    any one can be omitted, or replaced with None.
     67    For "show details", possible values are None, True and False,
     68    where True means initially opened, False and None the opposite.
     69    Prefix is written without final dot, and used in
     70    "prefix.part.*"-style pattern matching, where
     71    the first matched pattern is chosen.
     72    Prefix can also be set to None, which means, do never show these stack items.
     73    Unless overridden, installed apps are also colorized,
     74    and special 'INSTALLED_APPS' constant is used for them.
     75    You can also set your own pattern matcher,
     76    please see TRACEBACK_FRAME_COLORS below.
     77    """
     78    TRACEBACK_COLOR_SCHEME = {
     79        'django.template': ('#ffa', '#ffffe2'),
     80        'django.contrib': ('#fda', '#efd'),
     81        'django.utils': ('#cda', '#efd'),
     82        'django.db': ('#cfb', '#efd'),
     83        'django': ('#cfb','#efd'),
     84        'sqlite3': ('#cfe',''),
     85        'psycopg2': ('#cfe',),
     86        'INSTALLED_APPS': ('#ddf', '#fffff2'),
     87        '': ('#bbe', ),
     88    }
     89    scheme = getattr(settings, 'TRACEBACK_COLOR_SCHEME', TRACEBACK_COLOR_SCHEME)
     90    return scheme
     91
     92def get_traceback_frame_colors(module_name, tb_frame):
     93    """
     94    For python module name (like, "django.template.__init__"),
     95    returns the first prefix-matched color. By default, it's
     96    "django.*" rule.
     97    Default colors are passed as empty module_name, if module name
     98    can't be determined, empty string is assumed.
     99    Output format: safe-pattern-name, colors
     100    Colors is tuple of (bg color, wrapper bg color, text color),
     101    last colors can be omitted.
     102    Pattern name is encoded to be safe css class name.
     103    You're able to make your completely own colors matcher,
     104    set TRACEBACK_FRAME_COLORS to your function then.
     105    """
     106    if hasattr(settings, 'TRACEBACK_FRAME_COLORS'):
     107        return getattr(settings, 'TRACEBACK_FRAME_COLORS')(module_name)
     108   
     109    scheme = get_traceback_color_scheme()
     110   
     111    #sort keys so a.b is before a, and empty key is the last
     112    keys = sorted(scheme.keys(), reverse=True)
     113   
     114    for prefix in keys:
     115        if module_name.startswith(prefix+'.') or module_name == prefix:
     116            return prefix
     117
     118    for prefix in getattr(settings, 'INSTALLED_APPS', ()):
     119        if module_name.startswith(prefix+'.') or module_name == prefix:
     120            return 'INSTALLED_APPS'
     121   
     122    return ''
     123
    62124class ExceptionReporter(object):
    63125    """
    64126    A class to organize and coordinate reporting on exceptions.
     
    78140        if isinstance(self.exc_type, basestring):
    79141            self.exc_value = Exception('Deprecated String Exception: %r' % self.exc_type)
    80142            self.exc_type = type(self.exc_value)
     143   
     144    def get_frame_colors_css(self, existing_types):
     145        required_types = set(['']) | set(existing_types)
     146       
     147        color_fixes = [
     148            '.frame%s div.context ol.context-line li { background-color:%s; }',
     149            'ul.traceback li.frame%s { background-color: %s;}',
     150            '.frame%s div.context ol.context-line li { color:%s; }',
     151        ]
     152        visibility_fixes = [
     153            '.frame%s div.context ol.pre-context { display:block !important; }'
     154            '.frame%s div.context ol.post-context { display:block !important; }'
     155        ]
     156       
     157        scheme = get_traceback_color_scheme()
    81158
     159        extra_styles = []
     160       
     161        for frame_type, frame_colors in scheme.iteritems():
     162            classes = frame_type.replace('.','-')
     163            if classes in required_types:
     164                classes = classes and '.'+classes or '' 
     165                for pos, attr in enumerate(frame_colors):
     166                    if attr:
     167                        if pos<3:
     168                            line = color_fixes[pos] % (classes, attr)
     169                            extra_styles.append(line)
     170                        else:
     171                            for fix in visibility_fixes:
     172                                extra_styles.append(fix % classes)
     173        return extra_styles
     174   
    82175    def get_traceback_html(self):
    83176        "Return HTML code for traceback."
    84177
     
    117210                frame['vars'] = [(k, force_escape(pprint(v))) for k, v in frame['vars']]
    118211            frames[i] = frame
    119212
     213
     214       
     215        existing_types = [frame['classes'] for frame in frames] 
     216        extra_styles = self.get_frame_colors_css(existing_types)
     217       
    120218        unicode_hint = ''
    121219        if self.exc_type and issubclass(self.exc_type, UnicodeError):
    122220            start = getattr(self.exc_value, 'start', None)
     
    128226        t = Template(TECHNICAL_500_TEMPLATE, name='Technical 500 template')
    129227        c = Context({
    130228            'is_email': self.is_email,
     229            'extra_styles': '\n    '.join(extra_styles),
    131230            'unicode_hint': unicode_hint,
    132231            'frames': frames,
    133232            'request': self.request,
     
    238337            function = tb.tb_frame.f_code.co_name
    239338            lineno = tb.tb_lineno - 1
    240339            loader = tb.tb_frame.f_globals.get('__loader__')
    241             module_name = tb.tb_frame.f_globals.get('__name__')
     340            module_name = tb.tb_frame.f_globals.get('__name__') or ''
     341            classes = get_traceback_frame_colors(module_name, tb.tb_frame)
    242342            pre_context_lineno, pre_context, context_line, post_context = self._get_lines_from_file(filename, lineno, 7, loader, module_name)
    243343            if pre_context_lineno is not None:
    244344                frames.append({
    245345                    'tb': tb,
     346                    'classes': classes.replace('.','-'),
    246347                    'filename': filename,
    247348                    'function': function,
    248349                    'lineno': lineno + 1,
     
    345446    div.context ol { padding-left:30px; margin:0 10px; list-style-position: inside; }
    346447    div.context ol li { font-family:monospace; white-space:pre; color:#666; cursor:pointer; }
    347448    div.context ol li pre { display:inline; }
    348     div.context ol.context-line li { color:black; background-color:#ccc; }
     449    div.context ol.context-line li { color:black; }
    349450    div.context ol.context-line li span { position:absolute; right:32px; }
    350451    div.commands { margin-left: 40px; }
    351452    div.commands a { color:black; text-decoration:none; }
     
    355456    #template, #template-not-exist { background:#f6f6f6; }
    356457    #template-not-exist ul { margin: 0 0 0 20px; }
    357458    #unicode-hint { background:#eee; }
    358     #traceback { background:#eee; }
     459    #traceback { background-color:#ffe; }
    359460    #requestinfo { background:#f6f6f6; padding-left:120px; }
    360461    #summary table { border:none; background:transparent; }
    361462    #requestinfo h2, #requestinfo h3 { position:relative; margin-left:-100px; }
     
    365466    h2 span.commands { font-size:.7em;}
    366467    span.commands a:link {color:#5E5694;}
    367468    pre.exception_value { font-family: sans-serif; color: #666; font-size: 1.5em; margin: 10px 0 10px 0; }
     469    {{ extra_styles }}
    368470  </style>
    369471  {% if not is_email %}
    370472  <script type="text/javascript">
     
    527629  <div id="browserTraceback">
    528630    <ul class="traceback">
    529631      {% for frame in frames %}
    530         <li class="frame">
     632        <li class="frame {{ frame.classes }}">
    531633          <code>{{ frame.filename|escape }}</code> in <code>{{ frame.function|escape }}</code>
    532634
    533635          {% if frame.context_line %}
Back to Top