osv_memory classes seem to share their _columns?

Asked by John B

Before I put together a more complicated scenario, maybe someone can explain the behaviour I'm seeing if it isn't a bug.

I have two osv_memory wizards in separate classes which create dynamic forms. If I launch WizardA and then launch WizardB, the columns from WizardA are now attributes of WizardB as well. So if I print self._columns when launching WizardB, I'll see all of it's columns plus WizACol1, WizACol2, etc, etc. These don't show up on the form itself, but I believe it's causing a couple of issues elsewhere for me.

So... why is WizardB being instantiated with WizardA's columns? The columns (should) belong to WizardA, not WizardB or their parent class osv_memory. Am I missing something?

Let me know if a test module is required to demonstrate, or if I'm simply missing something obvious. Thanks!

Question information

Language:
English Edit question
Status:
Solved
For:
Odoo Server (MOVED TO GITHUB) Edit question
Assignee:
No assignee Edit question
Solved by:
Olivier Dony (Odoo)
Solved:
Last query:
Last reply:
Revision history for this message
Olivier Dony (Odoo) (odo-openerp) said :
#1

(converting to a question, as this is not really a bug)

Revision history for this message
Best Olivier Dony (Odoo) (odo-openerp) said :
#2

Hi John,

Thanks for providing the test module, it makes your question definitely easier to understand :-)

Your reasoning is correct, but you have overlooked one thing: all osv classes (osv or osv_memory) are supposed to have their own _columns attribute. This is partly due to the internal ORM mechanics for OpenERP inheritance, and partly due to the way Python's own object inheritance works.

To get the correct behavior, make sure to initialize at least an empty _columns dictionary in both wizards. For example add this line right after the declaration of _name or _description:
  _columns = {}

Now on a related note, your wizards seem to do something that is really *not* recommended: altering the _columns of the wizard class itself. This is bad for many reasons, such as interactions by multiple instances, memory leaks, etc.
You may have seen this technique used in other addons, but this should really be avoided.
Instead, consider 2 alternatives:
1) Use "virtual" fields, which are returned in fields_view_get() as if they existed, and handle these virtual fields values properly by overriding read() and write() appropriately, without actually modifying _columns at any time.
2) Instead of creating dynamic fields on the wizard object, have a child osv_memory object displayed in a one2many widget. This way you can have any number of lines and fields (you can even make the o2m list editable, or display it in form view directly, like addresses on partners).

Hope this helps....

Revision history for this message
John B (johnb-ca) said :
#3

Thanks Olivier, that's a great response!

I have a few wizards using this approach so I'll need to update them. Do you know of a good example of the first alternative off the top of your head? If not, I'll start poking around.

Thanks again!

Revision history for this message
John B (johnb-ca) said :
#4

Thanks Olivier Dony (OpenERP), that solved my question.

Revision history for this message
Alexis de Lattre (alexis-via) said :
#5

The problem is that, in many places in the addons, there are some wizards without _columns = {} declaration. And it causes very tricky bugs which are very hard to reproduce. Here are some examples of bugs caused by this problem :

https://bugs.launchpad.net/openobject-addons/+bug/997160
https://bugs.launchpad.net/openobject-client/+bug/789074

So, if we have to decle _columns = {} in the wizards that don't have any fields, all the wizards of the addons should be reviewed and many of them should probably be fixed !

Alexis, who lost many hours because of this issue !