Property methods: add to depends or not?

I define a property method:

@property
def grammage(self):
    if self.product and self.product.grammage:
        return self.product.grammage

Add “grammage” depends on on_change methods:

@fields.depends('grammage')
def on_change_length(self):
    if self.grammage:
        ....

The question is: we need to add “grammage” in the depends or not? When pass the tests:

  • In case add the depends I get error:
Traceback (most recent call last):
  File "/home/raimon/projectes/nandev/trytond/trytond/tests/test_tryton.py", line 203, in wrapper
    result = func(*args, **kwargs)
  File "/home/raimon/projectes/nandev/trytond/trytond/tests/test_tryton.py", line 388, in test_depends
    test_depend_exists(model, depend, qualname)
  File "/home/raimon/projectes/nandev/trytond/trytond/tests/test_tryton.py", line 374, in test_depend_exists
    'Unknonw "%s" in %s' % (depend, qualname))
AssertionError: Unknonw "grammage" in "purchase.line"."length"."on_change"
  • In case we not add “grammage” at depends, I get the error:
Traceback (most recent call last):
  File "/home/raimon/projectes/nandev/trytond/trytond/tests/test_tryton.py", line 203, in wrapper
    result = func(*args, **kwargs)
  File "/home/raimon/projectes/nandev/trytond/trytond/tests/test_tryton.py", line 443, in test_field_methods
  File "/home/raimon/projectes/nandev/trytond/trytond/model/modelview.py", line 89, in wrapper
    result = func(self, *args, **kwargs)
  File "/home/raimon/projectes/nandev/trytond/trytond/model/fields/field.py", line 117, in wrapper
    return func(self, *args, **kwargs)
  File "/home/raimon/projectes/nandev/trytond/trytond/modules/customer/quote.py", line 531, in on_change_sheet
    super(Quote, self).on_change_sheet()
  File "/home/raimon/projectes/nandev/trytond/trytond/model/fields/field.py", line 117, in wrapper
    return func(self, *args, **kwargs)
  File "/home/raimon/projectes/nandev/trytond/trytond/modules/customer/sheet.py", line 100, in on_change_sheet
    if self.grammage and self.length and self.sheet and self.width:
  File "/home/raimon/projectes/nandev/trytond/trytond/model/modelstorage.py", line 1403, in __getattr__
    return super(ModelStorage, self).__getattr__(name)
  File "/home/raimon/projectes/nandev/trytond/trytond/model/model.py", line 280, in __getattr__
    % (self.__name__, name, self._values))
AttributeError: 'customer.quote' Model has no attribute 'grammage': {'quantity': None, 'discount': None, 'gross_unit_price': None, 'sheet': None, 'width': None, 'length': None, 'product': None}

I think test_depend_exists() [1] we need to check depends is a field or a method.

[1] https://github.com/tryton/trytond/blob/develop/trytond/tests/test_tryton.py#L372

@property are delicate to use, because if anything raises an AttributeError inside them, Tryton raises your second error (basically, the AttributeError from inside the property code is interpreted as a non-existing Tryton field).

In your case, you should probably add the product field to your @depends rather then the grammage property.

Edit: Typo

Why you define the property?

I will avoid defining properties if they are not really required.

If the property is just a shourt-cut for getting the gramamge of the product I will prefer to write the full expression on each place that is used.

If you need some property to be customized and used on on_change I will probably use a Function field with on_change_with.

If you just need to be able to customize some behaviour of the code (which is not called with on change), you can use a property which is simplier to write

As you can see, there is no solution for all cases.

Indeed you can use a method and decorate it with the fields.depends.

I’m wondering if it would be possible for fields.depends to support also properties. It may be complicated but it would be a nice improvement.