#19616: QuerySet.__contains__ tries to check the length of a None
-------------------------------------+-------------------------------------
     Reporter:  kalugny@…            |                    Owner:  nobody
         Type:  Bug                  |                   Status:  new
    Component:  Database layer       |                  Version:  1.4
  (models, ORM)                      |               Resolution:
     Severity:  Normal               |             Triage Stage:
     Keywords:                       |  Unreviewed
    Has patch:  0                    |      Needs documentation:  0
  Needs tests:  0                    |  Patch needs improvement:  0
Easy pickings:  1                    |                    UI/UX:  0
-------------------------------------+-------------------------------------

Old description:

> This is the code from QuerySet (version 1.42).
> As you can see by the lines I've bolded, although _result_cache might be
> None, it is still being checked for len()
>
> def __contains__(self, val):
>         # The 'in' operator works without this method, due to __iter__.
> This
>         # implementation exists only to shortcut the creation of Model
>         # instances, by bailing out early if we find a matching element.
>         pos = 0
>         '''if self._result_cache is not None:'''
>             if val in self._result_cache:
>                 return True
>             elif self._iter is None:
>                 # iterator is exhausted, so we have our answer
>                 return False
>             # remember not to check these again:
>             pos = len(self._result_cache)
>         '''else:'''
>             # We need to start filling the result cache out. The
> following
>             # ensures that self._iter is not None and self._result_cache
> is not
>             # None
>             it = iter(self)
>
>         # Carry on, one result at a time.
>         while True:
>            ''' if len(self._result_cache) <= pos:'''
>                 self._fill_cache(num=1)

New description:

 This is the code from QuerySet (version 1.42).
 As you can see by the lines I've bolded, although _result_cache might be
 None, it is still being checked for len()
 {{{
 def __contains__(self, val):
         # The 'in' operator works without this method, due to __iter__.
 This
         # implementation exists only to shortcut the creation of Model
         # instances, by bailing out early if we find a matching element.
         pos = 0
         if self._result_cache is not None:
             if val in self._result_cache:
                 return True
             elif self._iter is None:
                 # iterator is exhausted, so we have our answer
                 return False
             # remember not to check these again:
             pos = len(self._result_cache)
         else:
             # We need to start filling the result cache out. The following
             # ensures that self._iter is not None and self._result_cache
 is not
             # None
             it = iter(self)

         # Carry on, one result at a time.
         while True:
            if len(self._result_cache) <= pos:
                 self._fill_cache(num=1)
 }}}

--

Comment (by lukeplant):

 Looking at the code and the comments in the `else` branch, it actually
 seems very obvious that the function has covered it's bases about whether
 self._result_cache is `None` or not. We need either some further analysis
 as to why it is wrong, or a simple test case that ought to work.

-- 
Ticket URL: <https://code.djangoproject.com/ticket/19616#comment:3>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to