Why some operators are not working as expected with recordsets in Odoo?
Asked Answered
E

2

5

I have done some tests:

>>> empty_recordset = self.env['res.users']                                 # empty recordset
>>> not_empty_recordset = self.env['res.users'].search([('id', '=', 1)])    # recordset with one record

>>> empty_recordset is False
False

>>> empty_recordset is None
False

>>> empty_recordset == False
False

>>> empty_recordset == True
False

>>> bool(empty_recordset)
False

>>> not empty_recordset
True

>>> if empty_recordset:           # it is treated as False
...     print('hello')
... 

>>> bool(not_empty_recordset)
True

>>> if not_empty_recordset:
...     print('hello')
... 
hello

>>> not not_empty_recordset
False
  • When the recordset is cast with bool() it returns True or False.
  • With if and not statements the result is the expected as well.
  • But when it is used with the operators is, ==, != the result is not the expected.

What is happening? Is the recordset treated as a boolean value only with the if and not statements? Are the rest of the operators not overloaded?

Essam answered 12/12, 2017 at 17:29 Comment(0)
O
3

It's the way __nonzero__ is implemented:

Called to implement truth value testing and the built-in operation bool(); should return False or True, or their integer equivalents 0 or 1. When this method is not defined, len() is called, if it is defined, and the object is considered true if its result is nonzero. If a class defines neither len() nor nonzero(), all its instances are considered true.

You can check it on odoo/odoo/models.py:

For Odoo 10 the code is:

def __nonzero__(self):
    """ Test whether ``self`` is nonempty. """
    return bool(getattr(self, '_ids', True))
Oxidate answered 12/12, 2017 at 18:25 Comment(0)
S
3

In addition to Lucas answer that explain all. in python all operation are converted to method calls

      if object: 
       #  is turned to. 
      if object.__nonzero__():

And

      if object == value:
      #is turned to
      if object.__eq__(value):

even this is:

      object + value
      # is converted go this
      object.__add__(value) 

All operators have there matching methods.

And this why you got different result when you changed the operator, because python calls under the hood a different method.

Stupe answered 12/12, 2017 at 21:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.