Search code examples
python-2.7operator-overloadingodoo-8odoorecordset

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


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?


Solution

  • 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))