Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 452
ChesuCR Avatar asked Dec 12 '17 17:12

ChesuCR


2 Answers

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))
like image 86
Lucas Avatar answered Oct 02 '22 05:10

Lucas


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.

like image 43
Charif DZ Avatar answered Oct 02 '22 05:10

Charif DZ