Django

Code

Changeset 7937

Show
Ignore:
Timestamp:
07/16/08 16:12:43 (4 months ago)
Author:
brosner
Message:

newforms-admin: Merged from trunk up to [7928].

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/branches/newforms-admin

    • Property svnmerge-integrated changed from /django/trunk:1-4345,4350-4357,4359-4365,4371-4372,4374-4377,4380-4386,4388,4390-4391,4400-4402,4404-4408,4410,4412-4419,4426-4427,4430-4432,4434,4441,4443-4444,4446-4447,4450,4452-4453,4455-4458,4476,4503,4546,4564-4569,4580-4586,4617,4630,4641-6390,6392-7921 to /django/trunk:1-4345,4350-4357,4359-4365,4371-4372,4374-4377,4380-4386,4388,4390-4391,4400-4402,4404-4408,4410,4412-4419,4426-4427,4430-4432,4434,4441,4443-4444,4446-4447,4450,4452-4453,4455-4458,4476,4503,4546,4564-4569,4580-4586,4617,4630,4641-6390,6392-7936
  • django/branches/newforms-admin/django/core/handlers/base.py

    r7881 r7937  
    6161        "Returns an HttpResponse object for the given HttpRequest" 
    6262        from django.core import exceptions, urlresolvers 
    63         from django.core.mail import mail_admins 
    6463        from django.conf import settings 
    6564 
     
    123122            if settings.DEBUG_PROPAGATE_EXCEPTIONS: 
    124123                raise 
    125             elif settings.DEBUG: 
    126                 from django.views import debug 
    127                 return debug.technical_500_response(request, *exc_info) 
    128             else: 
    129                 # When DEBUG is False, send an error message to the admins. 
    130                 subject = 'Error (%s IP): %s' % ((request.META.get('REMOTE_ADDR') in settings.INTERNAL_IPS and 'internal' or 'EXTERNAL'), request.path) 
    131                 try: 
    132                     request_repr = repr(request) 
    133                 except: 
    134                     request_repr = "Request repr() unavailable" 
    135                 message = "%s\n\n%s" % (self._get_traceback(exc_info), request_repr) 
    136                 mail_admins(subject, message, fail_silently=True) 
    137                 # Return an HttpResponse that displays a friendly error message. 
    138                 callback, param_dict = resolver.resolve500() 
    139                 return callback(request, **param_dict) 
     124            return self.handle_uncaught_exception(request, resolver, exc_info) 
     125 
     126    def handle_uncaught_exception(self, request, resolver, exc_info): 
     127        """ 
     128        Processing for any otherwise uncaught exceptions (those that will 
     129        generate HTTP 500 responses). Can be overridden by subclasses who want 
     130        customised 500 handling. 
     131 
     132        Be *very* careful when overriding this because the error could be 
     133        caused by anything, so assuming something like the database is always 
     134        available would be an error. 
     135        """ 
     136        from django.conf import settings 
     137        from django.core.mail import mail_admins 
     138 
     139        if settings.DEBUG: 
     140            from django.views import debug 
     141            return debug.technical_500_response(request, *exc_info) 
     142 
     143        # When DEBUG is False, send an error message to the admins. 
     144        subject = 'Error (%s IP): %s' % ((request.META.get('REMOTE_ADDR') in settings.INTERNAL_IPS and 'internal' or 'EXTERNAL'), request.path) 
     145        try: 
     146            request_repr = repr(request) 
     147        except: 
     148            request_repr = "Request repr() unavailable" 
     149        message = "%s\n\n%s" % (self._get_traceback(exc_info), request_repr) 
     150        mail_admins(subject, message, fail_silently=True) 
     151        # Return an HttpResponse that displays a friendly error message. 
     152        callback, param_dict = resolver.resolve500() 
     153        return callback(request, **param_dict) 
    140154 
    141155    def _get_traceback(self, exc_info=None): 
  • django/branches/newforms-admin/django/db/backends/__init__.py

    r7853 r7937  
    5454    interprets_empty_strings_as_nulls = False 
    5555    date_field_supports_time_value = True 
     56    can_use_chunked_reads = True 
    5657 
    5758class BaseDatabaseOperations(object): 
  • django/branches/newforms-admin/django/db/backends/sqlite3/base.py

    r7479 r7937  
    4141class DatabaseFeatures(BaseDatabaseFeatures): 
    4242    supports_constraints = False 
     43    # SQLite cannot handle us only partially reading from a cursor's result set 
     44    # and then writing the same rows to the database in another cursor. This 
     45    # setting ensures we always read result sets fully into memory all in one 
     46    # go. 
     47    can_use_chunked_reads = False 
    4348 
    4449class DatabaseOperations(BaseDatabaseOperations): 
  • django/branches/newforms-admin/django/db/models/sql/query.py

    r7922 r7937  
    16171617        # The MULTI case. 
    16181618        if self.ordering_aliases: 
    1619             return order_modified_iter(cursor, len(self.ordering_aliases), 
     1619            result = order_modified_iter(cursor, len(self.ordering_aliases), 
    16201620                    self.connection.features.empty_fetchmany_value) 
    1621         return iter((lambda: cursor.fetchmany(GET_ITERATOR_CHUNK_SIZE)), 
     1621        result = iter((lambda: cursor.fetchmany(GET_ITERATOR_CHUNK_SIZE)), 
    16221622                self.connection.features.empty_fetchmany_value) 
     1623        if not self.connection.features.can_use_chunked_reads: 
     1624            # If we are using non-chunked reads, we return the same data 
     1625            # structure as normally, but ensure it is all read into memory 
     1626            # before going any further. 
     1627            return list(result) 
     1628        return result 
    16231629 
    16241630# Use the backend's custom Query class if it defines one. Otherwise, use the 
  • django/branches/newforms-admin/django/views/debug.py

    r7881 r7937  
    1919        p = template_source.find('\n', p+1) 
    2020    yield len(template_source) + 1 
    21  
    22 def get_template_exception_info(exc_type, exc_value, tb): 
    23     origin, (start, end) = exc_value.source 
    24     template_source = origin.reload() 
    25     context_lines = 10 
    26     line = 0 
    27     upto = 0 
    28     source_lines = [] 
    29     before = during = after = "" 
    30     for num, next in enumerate(linebreak_iter(template_source)): 
    31         if start >= upto and end <= next: 
    32             line = num 
    33             before = escape(template_source[upto:start]) 
    34             during = escape(template_source[start:end]) 
    35             after = escape(template_source[end:next]) 
    36         source_lines.append( (num, escape(template_source[upto:next])) ) 
    37         upto = next 
    38     total = len(source_lines) 
    39  
    40     top = max(1, line - context_lines) 
    41     bottom = min(total, line + 1 + context_lines) 
    42  
    43     template_info = { 
    44         'message': exc_value.args[0], 
    45         'source_lines': source_lines[top:bottom], 
    46         'before': before, 
    47         'during': during, 
    48         'after': after, 
    49         'top': top, 
    50         'bottom': bottom, 
    51         'total': total, 
    52         'line': line, 
    53         'name': origin.name, 
    54     } 
    55     exc_info = hasattr(exc_value, 'exc_info') and exc_value.exc_info or (exc_type, exc_value, tb) 
    56     return exc_info + (template_info,) 
    5721 
    5822def get_safe_settings(): 
     
    7236    the values returned from sys.exc_info() and friends. 
    7337    """ 
    74     html = get_traceback_html(request, exc_type, exc_value, tb) 
     38    reporter = ExceptionReporter(request, exc_type, exc_value, tb) 
     39    html = reporter.get_traceback_html() 
    7540    return HttpResponseServerError(html, mimetype='text/html') 
    7641 
    77 def get_traceback_html(request, exc_type, exc_value, tb): 
    78     "Return HTML code for traceback." 
    79     template_info = None 
    80     template_does_not_exist = False 
    81     loader_debug_info = None 
    82  
    83     # Handle deprecated string exceptions 
    84     if isinstance(exc_type, basestring): 
    85         exc_value = Exception('Deprecated String Exception: %r' % exc_type) 
    86         exc_type = type(exc_value) 
    87  
    88     if issubclass(exc_type, TemplateDoesNotExist): 
    89         from django.template.loader import template_source_loaders 
    90         template_does_not_exist = True 
    91         loader_debug_info = [] 
    92         for loader in template_source_loaders: 
     42class ExceptionReporter: 
     43    """ 
     44    A class to organize and coordinate reporting on exceptions. 
     45    """ 
     46    def __init__(self, request, exc_type, exc_value, tb): 
     47        self.request = request 
     48        self.exc_type = exc_type 
     49        self.exc_value = exc_value 
     50        self.tb = tb 
     51 
     52        self.template_info = None 
     53        self.template_does_not_exist = False 
     54        self.loader_debug_info = None 
     55 
     56        # Handle deprecated string exceptions 
     57        if isinstance(self.exc_type, basestring): 
     58            self.exc_value = Exception('Deprecated String Exception: %r' % self.exc_type) 
     59            self.exc_type = type(self.exc_value) 
     60 
     61    def get_traceback_html(self): 
     62        "Return HTML code for traceback." 
     63 
     64        if issubclass(self.exc_type, TemplateDoesNotExist): 
     65            from django.template.loader import template_source_loaders 
     66            self.template_does_not_exist = True 
     67            self.loader_debug_info = [] 
     68            for loader in template_source_loaders: 
     69                try: 
     70                    source_list_func = getattr(__import__(loader.__module__, {}, {}, ['get_template_sources']), 'get_template_sources') 
     71                    # NOTE: This assumes exc_value is the name of the template that 
     72                    # the loader attempted to load. 
     73                    template_list = [{'name': t, 'exists': os.path.exists(t)} \ 
     74                        for t in source_list_func(str(self.exc_value))] 
     75                except (ImportError, AttributeError): 
     76                    template_list = [] 
     77                self.loader_debug_info.append({ 
     78                    'loader': loader.__module__ + '.' + loader.__name__, 
     79                    'templates': template_list, 
     80                }) 
     81        if settings.TEMPLATE_DEBUG and hasattr(self.exc_value, 'source'): 
     82            self.get_template_exception_info() 
     83 
     84        frames = self.get_traceback_frames() 
     85 
     86        unicode_hint = '' 
     87        if issubclass(self.exc_type, UnicodeError): 
     88            start = getattr(self.exc_value, 'start', None) 
     89            end = getattr(self.exc_value, 'end', None) 
     90            if start is not None and end is not None: 
     91                unicode_str = self.exc_value.args[1] 
     92                unicode_hint = smart_unicode(unicode_str[max(start-5, 0):min(end+5, len(unicode_str))], 'ascii', errors='replace') 
     93        from django import get_version 
     94        t = Template(TECHNICAL_500_TEMPLATE, name='Technical 500 template') 
     95        c = Context({ 
     96            'exception_type': self.exc_type.__name__, 
     97            'exception_value': smart_unicode(self.exc_value, errors='replace'), 
     98            'unicode_hint': unicode_hint, 
     99            'frames': frames, 
     100            'lastframe': frames[-1], 
     101            'request': self.request, 
     102            'request_protocol': self.request.is_secure() and "https" or "http", 
     103            'settings': get_safe_settings(), 
     104            'sys_executable': sys.executable, 
     105            'sys_version_info': '%d.%d.%d' % sys.version_info[0:3], 
     106            'server_time': datetime.datetime.now(), 
     107            'django_version_info': get_version(), 
     108            'sys_path' : sys.path, 
     109            'template_info': self.template_info, 
     110            'template_does_not_exist': self.template_does_not_exist, 
     111            'loader_debug_info': self.loader_debug_info, 
     112        }) 
     113        return t.render(c) 
     114 
     115    def get_template_exception_info(self): 
     116        origin, (start, end) = self.exc_value.source 
     117        template_source = origin.reload() 
     118        context_lines = 10 
     119        line = 0 
     120        upto = 0 
     121        source_lines = [] 
     122        before = during = after = "" 
     123        for num, next in enumerate(linebreak_iter(template_source)): 
     124            if start >= upto and end <= next: 
     125                line = num 
     126                before = escape(template_source[upto:start]) 
     127                during = escape(template_source[start:end]) 
     128                after = escape(template_source[end:next]) 
     129            source_lines.append( (num, escape(template_source[upto:next])) ) 
     130            upto = next 
     131        total = len(source_lines) 
     132 
     133        top = max(1, line - context_lines) 
     134        bottom = min(total, line + 1 + context_lines) 
     135 
     136        self.template_info = { 
     137            'message': self.exc_value.args[0], 
     138            'source_lines': source_lines[top:bottom], 
     139            'before': before, 
     140            'during': during, 
     141            'after': after, 
     142            'top': top, 
     143            'bottom': bottom, 
     144            'total': total, 
     145            'line': line, 
     146            'name': origin.name, 
     147        } 
     148        if hasattr(self.exc_value, 'exc_info') and self.exc_value.exc_info: 
     149            exc_type, exc_value, tb = self.exc_value.exc_info 
     150 
     151    def _get_lines_from_file(self, filename, lineno, context_lines, loader=None, module_name=None): 
     152        """ 
     153        Returns context_lines before and after lineno from file. 
     154        Returns (pre_context_lineno, pre_context, context_line, post_context). 
     155        """ 
     156        source = None 
     157        if loader is not None and hasattr(loader, "get_source"): 
     158            source = loader.get_source(module_name) 
     159            if source is not None: 
     160                source = source.splitlines() 
     161        if source is None: 
    93162            try: 
    94                 source_list_func = getattr(__import__(loader.__module__, {}, {}, ['get_template_sources']), 'get_template_sources') 
    95                 # NOTE: This assumes exc_value is the name of the template that 
    96                 # the loader attempted to load. 
    97                 template_list = [{'name': t, 'exists': os.path.exists(t)} \ 
    98                     for t in source_list_func(str(exc_value))] 
    99             except (ImportError, AttributeError): 
    100                 template_list = [] 
    101             loader_debug_info.append({ 
    102                 'loader': loader.__module__ + '.' + loader.__name__, 
    103                 'templates': template_list, 
    104             }) 
    105     if settings.TEMPLATE_DEBUG and hasattr(exc_value, 'source'): 
    106         exc_type, exc_value, tb, template_info = get_template_exception_info(exc_type, exc_value, tb) 
    107     frames = [] 
    108     while tb is not None: 
    109         # support for __traceback_hide__ which is used by a few libraries 
    110         # to hide internal frames. 
    111         if tb.tb_frame.f_locals.get('__traceback_hide__'): 
     163                f = open(filename) 
     164                try: 
     165                    source = f.readlines() 
     166                finally: 
     167                    f.close() 
     168            except (OSError, IOError): 
     169                pass 
     170        if source is None: 
     171            return None, [], None, [] 
     172 
     173        encoding = 'ascii' 
     174        for line in source[:2]: 
     175            # File coding may be specified. Match pattern from PEP-263 
     176            # (http://www.python.org/dev/peps/pep-0263/) 
     177            match = re.search(r'coding[:=]\s*([-\w.]+)', line) 
     178            if match: 
     179                encoding = match.group(1) 
     180                break 
     181        source = [unicode(sline, encoding, 'replace') for sline in source] 
     182 
     183        lower_bound = max(0, lineno - context_lines) 
     184        upper_bound = lineno + context_lines 
     185 
     186        pre_context = [line.strip('\n') for line in source[lower_bound:lineno]] 
     187        context_line = source[lineno].strip('\n') 
     188        post_context = [line.strip('\n') for line in source[lineno+1:upper_bound]] 
     189 
     190        return lower_bound, pre_context, context_line, post_context 
     191 
     192    def get_traceback_frames(self): 
     193        frames = [] 
     194        tb = self.tb 
     195        while tb is not None: 
     196            # support for __traceback_hide__ which is used by a few libraries 
     197            # to hide internal frames. 
     198            if tb.tb_frame.f_locals.get('__traceback_hide__'): 
     199                tb = tb.tb_next 
     200                continue 
     201            filename = tb.tb_frame.f_code.co_filename 
     202            function = tb.tb_frame.f_code.co_name 
     203            lineno = tb.tb_lineno - 1 
     204            loader = tb.tb_frame.f_globals.get('__loader__') 
     205            module_name = tb.tb_frame.f_globals.get('__name__') 
     206            pre_context_lineno, pre_context, context_line, post_context = self._get_lines_from_file(filename, lineno, 7, loader, module_name) 
     207            if pre_context_lineno is not None: 
     208                frames.append({ 
     209                    'tb': tb, 
     210                    'filename': filename, 
     211                    'function': function, 
     212                    'lineno': lineno + 1, 
     213                    'vars': tb.tb_frame.f_locals.items(), 
     214                    'id': id(tb), 
     215                    'pre_context': pre_context, 
     216                    'context_line': context_line, 
     217                    'post_context': post_context, 
     218                    'pre_context_lineno': pre_context_lineno + 1, 
     219                }) 
    112220            tb = tb.tb_next 
    113             continue 
    114         filename = tb.tb_frame.f_code.co_filename 
    115         function = tb.tb_frame.f_code.co_name 
    116         lineno = tb.tb_lineno - 1 
    117         loader = tb.tb_frame.f_globals.get('__loader__') 
    118         module_name = tb.tb_frame.f_globals.get('__name__') 
    119         pre_context_lineno, pre_context, context_line, post_context = _get_lines_from_file(filename, lineno, 7, loader, module_name) 
    120         if pre_context_lineno is not None: 
    121             frames.append({ 
    122                 'tb': tb, 
    123                 'filename': filename, 
    124                 'function': function, 
    125                 'lineno': lineno + 1, 
    126                 'vars': tb.tb_frame.f_locals.items(), 
    127                 'id': id(tb), 
    128                 'pre_context': pre_context, 
    129                 'context_line': context_line, 
    130                 'post_context': post_context, 
    131                 'pre_context_lineno': pre_context_lineno + 1, 
    132             }) 
    133         tb = tb.tb_next 
    134  
    135     if not frames: 
    136         frames = [{ 
    137             'filename': '&lt;unknown&gt;', 
    138             'function': '?', 
    139             'lineno': '?', 
    140         }] 
    141  
    142     unicode_hint = '' 
    143     if issubclass(exc_type, UnicodeError): 
    144         start = getattr(exc_value, 'start', None) 
    145         end = getattr(exc_value, 'end', None) 
    146         if start is not None and end is not None: 
    147             unicode_str = exc_value.args[1] 
    148             unicode_hint = smart_unicode(unicode_str[max(start-5, 0):min(end+5, len(unicode_str))], 'ascii', errors='replace') 
    149     from django import get_version 
    150     t = Template(TECHNICAL_500_TEMPLATE, name='Technical 500 template') 
    151     c = Context({ 
    152         'exception_type': exc_type.__name__, 
    153         'exception_value': smart_unicode(exc_value, errors='replace'), 
    154         'unicode_hint': unicode_hint, 
    155         'frames': frames, 
    156         'lastframe': frames[-1], 
    157         'request': request, 
    158         'request_protocol': request.is_secure() and "https" or "http", 
    159         'settings': get_safe_settings(), 
    160         'sys_executable': sys.executable, 
    161         'sys_version_info': '%d.%d.%d' % sys.version_info[0:3], 
    162         'server_time': datetime.datetime.now(), 
    163         'django_version_info': get_version(), 
    164         'sys_path' : sys.path, 
    165         'template_info': template_info, 
    166         'template_does_not_exist': template_does_not_exist, 
    167         'loader_debug_info': loader_debug_info, 
    168     }) 
    169     return t.render(c) 
     221 
     222        if not frames: 
     223            frames = [{ 
     224                'filename': '&lt;unknown&gt;', 
     225                'function': '?', 
     226                'lineno': '?', 
     227                'context_line': '???', 
     228            }] 
     229 
     230        return frames 
     231 
     232    def format_exception(self): 
     233        """ 
     234        Return the same data as from traceback.format_exception. 
     235        """ 
     236        import traceback 
     237        frames = self.get_traceback_frames() 
     238        tb = [ (f['filename'], f['lineno'], f['function'], f['context_line']) for f in frames ] 
     239        list = ['Traceback (most recent call last):\n'] 
     240        list += traceback.format_list(tb) 
     241        list += traceback.format_exception_only(self.exc_type, self.exc_value) 
     242        return list 
     243 
    170244 
    171245def technical_404_response(request, exception): 
     
    199273    }) 
    200274    return HttpResponse(t.render(c), mimetype='text/html') 
    201  
    202 def _get_lines_from_file(filename, lineno, context_lines, loader=None, module_name=None): 
    203     """ 
    204     Returns context_lines before and after lineno from file. 
    205     Returns (pre_context_lineno, pre_context, context_line, post_context). 
    206     """ 
    207     source = None 
    208     if loader is not None and hasattr(loader, "get_source"): 
    209         source = loader.get_source(module_name) 
    210         if source is not None: 
    211             source = source.splitlines() 
    212     if source is None: 
    213         try: 
    214             f = open(filename) 
    215             try: 
    216                 source = f.readlines() 
    217             finally: 
    218                 f.close() 
    219         except (OSError, IOError): 
    220             pass 
    221     if source is None: 
    222         return None, [], None, [] 
    223  
    224     encoding = 'ascii' 
    225     for line in source[:2]: 
    226         # File coding may be specified. Match pattern from PEP-263 
    227         # (http://www.python.org/dev/peps/pep-0263/) 
    228         match = re.search(r'coding[:=]\s*([-\w.]+)', line) 
    229         if match: 
    230             encoding = match.group(1) 
    231             break 
    232     source = [unicode(sline, encoding, 'replace') for sline in source] 
    233  
    234     lower_bound = max(0, lineno - context_lines) 
    235     upper_bound = lineno + context_lines 
    236  
    237     pre_context = [line.strip('\n') for line in source[lower_bound:lineno]] 
    238     context_line = source[lineno].strip('\n') 
    239     post_context = [line.strip('\n') for line in source[lineno+1:upper_bound]] 
    240  
    241     return lower_bound, pre_context, context_line, post_context 
    242275 
    243276# 
  • django/branches/newforms-admin/tests/regressiontests/queries/models.py

    r7922 r7937  
    77 
    88from django.db import models 
    9 from django.db.models.query import Q 
     9from django.db.models.query import Q, ITER_CHUNK_SIZE 
    1010 
    1111# Python 2.3 doesn't have sorted() 
     
    1414except NameError: 
    1515    from django.utils.itercompat import sorted 
    16                  
     16 
    1717class Tag(models.Model): 
    1818    name = models.CharField(max_length=10) 
     
    821821[] 
    822822 
     823Bug #7411 - saving to db must work even with partially read result set in 
     824another cursor. 
     825 
     826>>> for num in range(2 * ITER_CHUNK_SIZE + 1): 
     827...     _ = Number.objects.create(num=num) 
     828 
     829>>> for i, obj in enumerate(Number.objects.all()): 
     830...     obj.save() 
     831...     if i > 10: break 
     832 
    823833"""} 
    824834