Search product or lot that the context has valid locations

I see in some modules (for example sale), product field has search_context with:

    'locations': If(Bool(Eval('warehouse')), [Eval('warehouse', -1)], []),
  • In case eval [-1], compute_quantities_query() method crash because is not valid location.
  • Also in other cases eval [None], current compute_quantities_query() not control locations are list of ids.

See those examples:

  1. Examples eval Pyson:
>>> from trytond import pyson
>>> eval = pyson.PYSONEncoder().encode(pyson.Bool(''))
>>> pyson.PYSONDecoder().decode(eval)
False
>>> eval = pyson.PYSONEncoder().encode(pyson.Bool(-1))
>>> pyson.PYSONDecoder().decode(eval)
True
>>> eval = pyson.PYSONEncoder().encode(pyson.Bool(None))
>>> pyson.PYSONDecoder().decode(eval)
False

  1. Example traceback when locations context has locations with -1:
>>> Product = pool.get('product.product')
>>> transaction.set_context(locations=[-1])
>>> Product.search([('code', '=', '0010003'), ('quantity', '>', 0)])

The traceback is:

Traceback (most recent call last):
  File "/home/raimon/projectes/nandev2/trytond/trytond/model/model.py", line 291, in __getattr__
    return self._values[name]
           ~~~~~~~~~~~~^^^^^^
TypeError: 'NoneType' object is not subscriptable

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/home/raimon/projectes/nandev2/trytond/trytond/model/modelsql.py", line 1517, in search
    tables, expression = cls.__search_query(domain, count, query, order)
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/raimon/projectes/nandev2/trytond/trytond/model/modelsql.py", line 1436, in __search_query
    tables, expression = cls.search_domain(domain)
                         ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/raimon/projectes/nandev2/trytond/trytond/model/modelsql.py", line 1656, in search_domain
    expression = convert(domain)
                 ^^^^^^^^^^^^^^^
  File "/home/raimon/projectes/nandev2/trytond/trytond/model/modelsql.py", line 1652, in convert
    return And((convert(d) for d in (
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/raimon/projectes/nandev2/trytond/trytond/model/modelsql.py", line 1652, in <genexpr>
    return And((convert(d) for d in (
                ^^^^^^^^^^
  File "/home/raimon/projectes/nandev2/trytond/trytond/model/modelsql.py", line 1643, in convert
    expression = field.convert_domain(domain, tables, cls)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/raimon/projectes/nandev2/trytond/trytond/model/fields/function.py", line 101, in convert_domain
    return getattr(Model, self.searcher)(self.name, domain)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/raimon/projectes/nandev2/trytond/trytond/modules/stock/product.py", line 216, in search_quantity
    return cls._search_quantity(name, location_ids, domain)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/raimon/projectes/nandev2/trytond/trytond/modules/stock/move.py", line 136, in _search_quantity
    query = Move.compute_quantities_query(
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/raimon/projectes/nandev2/trytond/trytond/modules/stock/move.py", line 1457, in compute_quantities_query
    location_query = location_ids[:]
                     ~~~~~~~~~~~~^^^~
  File "/home/raimon/projectes/nandev2/trytond/trytond/modules/stock/move.py", line 1645, in _location_children
    return Location.search(['OR',
       ^^^^^^^^^^^^^^^^^^^^
  File "/home/raimon/projectes/nandev2/trytond/trytond/model/modelstorage.py", line 1594, in __getattr__
    return super(ModelStorage, self).__getattr__(name)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/raimon/projectes/nandev2/trytond/trytond/model/model.py", line 293, in __getattr__
    raise AttributeError("'%s' Model has no attribute '%s': %s"
AttributeError: 'stock.location' Model has no attribute 'flat_childs': None
>>> 
  1. Example traceback when locations context has not valid ids:
>>> transaction.set_context(locations=[None])
>>> Product.search([('code', '=', '0010003'), ('quantity', '>', 0)])

The traceback is:

  File "/home/raimon/projectes/nandev2/trytond/trytond/modules/stock/move.py", line 1457, in compute_quantities_query
    location_query = location_ids[:]
                     ~~~~~~~~~~~~^^^~
  File "/home/raimon/projectes/nandev2/trytond/trytond/modules/stock/move.py", line 1644, in _location_children
    if nested_location_ids:
                    ^^^^^^^^
  File "/home/raimon/projectes/nandev2/trytond/trytond/model/modelstorage.py", line 672, in browse
    ids = list(map(int, ids))
          ^^^^^^^^^^^^^^^^^^^
TypeError: int() argument must be a string, a bytes-like object or a real number, not 'NoneType'

My question is we should control the context which are valid locations?

Please create an issue listing the steps to reproducte it.

This sounds like a wrong usage, you can not set locations to None.

See the request and traceback at Read valid locations from the context