Code

Opened 6 years ago

Closed 5 years ago

#7221 closed (fixed)

TypeErrors from Field.get_db_prep_lookup() get suppressed

Reported by: Gulopine Owned by: nobody
Component: Database layer (models, ORM) Version: master
Severity: Keywords:
Cc: Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: yes Patch needs improvement: no
Easy pickings: UI/UX:

Description

The custom model fields documentation for get_db_prep_lookup() show the ability to raise a TypeError as a way to prevent certain types of lookups from taking place. In practice, however, it seems this error gets suppressed somewhere along the line, result in the QuerySet returning an empty list.

The query doesn't actually get executed in the database, as it's possible to observe this behavior even without having a true database table backing up the model. Also, while TypeError gets eaten, ValueError passes through just fine. I haven't tried all error types, but AttributeError also gets suppressed in the same manner as TypeError.

Also of interest, when manually iterating over a QuerySet that should raise a TypeError, it does in fact raise the error appropriately. However, when simply calling list() on it, the bug shows up. The following interpreter session illustrates the problem and its many peculiarities.

>>> from django.db import models

>>> class TypeErrorField(models.TextField):
...     def get_db_prep_lookup(self, lookup_type, value):
...         raise TypeError("Lookups are prohibited.")

>>> class ValueErrorField(models.TextField):
...     def get_db_prep_lookup(self, lookup_type, value):
...         raise ValueError("Lookups are prohibited.")

>>> class Test(models.Model):
...     type_error = TypeErrorField()
...     value_error = ValueErrorField()
...     class Meta:
...         app_label = 'test'

>>> Test.objects.filter(type_error='test')
[]
>>> list(Test.objects.filter(type_error='test'))
[]
>>> [x for x in Test.objects.filter(type_error='test')]
Traceback (most recent call last):
  ...
TypeError: Lookups are prohibited.

>>> Test.objects.filter(value_error='test')
Traceback (most recent call last):
  ...
ValueError: Lookups are prohibited.

Whether the documentation is wrong, or the documentation, I'm not sure, but there's certainly a disconnect here. If it matters, this was tested on Windows Vista, Python 2.5, SQLite. I've tried to trace through the execution, but I was unable to find anything that would be suppressing the error.

Attachments (0)

Change History (5)

comment:1 Changed 6 years ago by ericholscher

  • milestone set to 1.0
  • Triage Stage changed from Unreviewed to Accepted

comment:2 Changed 6 years ago by ericholscher

  • Needs tests set

comment:3 Changed 6 years ago by ubernostrum

  • milestone changed from 1.0 to post-1.0

comment:4 Changed 5 years ago by anonymous

  • milestone post-1.0 deleted

Milestone post-1.0 deleted

comment:5 Changed 5 years ago by almir@…

  • Resolution set to fixed
  • Status changed from new to closed

FWIW, this can be closed (it raises all execptions just fine with current trunk)

Add Comment

Modify Ticket

Change Properties
<Author field>
Action
as closed
as The resolution will be set. Next status will be 'closed'
The resolution will be deleted. Next status will be 'new'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.