Allow None in Greater/Less PYSON
The default value in Eval() PYSON statement is "ignored".
If you define a domain that use a float field in a Greater/Less comparision, this error is raised:
Traceback (most recent call last):
File "/home/guillem/nan/projectes/tryton/tryton_issues/tryton_clean/tryton/gui/window/form.py", line 369, in sig_new
self.screen.new()
File "/home/guillem/nan/projectes/tryton/tryton_issues/tryton_clean/tryton/gui/window/view_form/screen/screen.py", line 545, in new
record = group.new(default)
File "/home/guillem/nan/projectes/tryton/tryton_issues/tryton_clean/tryton/gui/window/view_form/model/group.py", line 318, in new
record.default_get()
File "/home/guillem/nan/projectes/tryton/tryton_issues/tryton_clean/tryton/gui/window/view_form/model/record.py", line 369, in default_get
self.set_default(vals)
File "/home/guillem/nan/projectes/tryton/tryton_issues/tryton_clean/tryton/gui/window/view_form/model/record.py", line 433, in set_default
self.validate(softvalidation=True)
File "/home/guillem/nan/projectes/tryton/tryton_issues/tryton_clean/tryton/gui/window/view_form/model/record.py", line 396, in validate
if not field.validate(self, softvalidation, pre_validate):
File "/home/guillem/nan/projectes/tryton/tryton_issues/tryton_clean/tryton/gui/window/view_form/model/field.py", line 84, in validate
domain = simplify(self.validation_domains(record, pre_validate))
File "/home/guillem/nan/projectes/tryton/tryton_issues/tryton_clean/tryton/gui/window/view_form/model/field.py", line 438, in validation_domains
screen_domain, attr_domain = self.domains_get(record, pre_validate)
File "/home/guillem/nan/projectes/tryton/tryton_issues/tryton_clean/tryton/gui/window/view_form/model/field.py", line 51, in domains_get
attr_domain = record.expr_eval(self.attrs.get('domain', []))
File "/home/guillem/nan/projectes/tryton/tryton_issues/tryton_clean/tryton/gui/window/view_form/model/record.py", line 503, in expr_eval
val = PYSONDecoder(ctx).decode(expr)
File "/usr/local/lib/python2.7/dist-packages/simplejson/decoder.py", line 370, in decode
obj, end = self.raw_decode(s)
File "/usr/local/lib/python2.7/dist-packages/simplejson/decoder.py", line 400, in raw_decode
return self.scan_once(s, idx=_w(s, idx).end())
File "/home/guillem/nan/projectes/tryton/tryton_issues/tryton_clean/tryton/pyson.py", line 138, in _object_hook
return klass.eval(dct, self.__context)
File "/home/guillem/nan/projectes/tryton/tryton_issues/tryton_clean/tryton/pyson.py", line 354, in eval
dct = Greater._convert(dct)
File "/home/guillem/nan/projectes/tryton/tryton_issues/tryton_clean/tryton/pyson.py", line 349, in _convert
dct[i] = float(dct[i])
TypeError: float() argument must be a string or a number
To reproduce it in core modules and default branch, you can change the domain of "product" field in moves like this and try to create a new move:
product = fields.Many2One("product.product", "Product", required=True,
select=True, states=STATES,
# domain=[('type', '!=', 'service')],
domain=[
If(Eval('quantity', 0) > 0,
('type', '!=', 'service'),
('type', '=', 'service')),
],
depends=DEPENDS + ['quantity'])
If a default value for quantity is set (defining default_quantity static method), it doesn't happen.
The problem is in 'tryton' client code:
the window.view_form.model.record.Record.get_eval() function, at line 254 [1] sets into dictionary what is returned by field.get_eval(self). It is the field value or None if field is empty (this case).
This dictionary is used to fill the context [2] that is used by Eval [3]
So, the context ALLWAYS have all the fields (but they could have None as value) so when it uses the "get" method of dictionary to use the Eval default value, this default value is never used.
[1] http://hg.tryton.org/tryton/file/tip/tryton/gui/window/view_form/model/record.py#l254
[2] http://hg.tryton.org/tryton/file/tip/tryton/gui/window/view_form/model/record.py#l496
[3] http://hg.tryton.org/tryton/file/tip/tryton/pyson.py#l173