`_save_values` side-effect

Hi Tryton,

I have always wondered about a behavior of _save_values in the following case:

address = Pool().get('party.address')()
address.party = Pool().get('party.party')()

_ = address._save_values

# At this point, address.party is saved, even though no "save" call was
# actually made

For information, the relevant line is here : trytond: 1f35ba30a768 trytond/model/modelstorage.py

  • I understand why it is necessary to save the party to “generate” the _save_values for the address
  • I also understand that _save_values is not really meant to be used apart from when save is called, however I have found it very useful in some technical cases

Anyway, I think this behavior is strange, and would like to know the rationale behind it

  • _save_values “looks a lot” like it is a “readonly” function (because of its name, and how it is a property), and saving object is a really non-obvious (and dangerous) side-effect
  • The sneaky saving is not really efficient (in the case of a batch save)

I would really like to know how much of this is intended. I would assume it dates back to the Active Record migration, to maintain compatibility with some previous code.

Also, I think that when this is called outside of actually “saving” (meaning a direct call from inside save), it should probably be an error, because it will usually never be a desired behavior.

Thanks!

I agree that this side-effect is not clean.

I do not think it is to maintain any backward compatibility because such feature did not exist before.
But I guess it was coded like that because it is easy.

Yes, I think a good improvement would be to move this save call out of _save_values and put it in save(). So _save_values could raise an error if the target is not a store record.