[FIX] osv: _constraints can be inherited by redefining a constraint with the same name

Indeed, when we define an expression like

class bar(osv.osv):
  _inherit = 'bar.bar'

  def _check_foo(self, cr, uid, ids, context):
      return True

  _constraints = [ (_check_foo, "Foo failed!", ['foo']) ]

... it means that _check_foo will be passed as an *object* to the model's
structure of _constraints. Therefore, it would be unequal and just append
the list of any existing constraints. So, an older (_check_foo, , ['foo'])
would always remain active using the previous code. This has to do with
the _check_foo being an unbound (ie. not inheritable) function.

Now, we check the /string name/ of the function, too. We say that if the
inherited class's constraint function has the same name "_check_foo", the
old ones shall be replaced.

Note: this MAY introduce unpredictable results, if several modules try
to override the same inherited constraint. There is no guaranteed order
of inheritance. Please avoid using this feature unless necessary.

lp bug: https://launchpad.net/bugs/700451 fixed

bzr revid: odo@openerp.com-20110117094750-4lyzx165f1z1zgl4
This commit is contained in:
P. Christeas 2011-01-17 10:47:50 +01:00 committed by Olivier Dony
parent 7c95acb04c
commit 814c4af299
1 changed files with 6 additions and 1 deletions

View File

@ -340,7 +340,12 @@ class osv(osv_base, orm.orm):
exist = False
for c2 in range(len(new)):
#For _constraints, we should check field and methods as well
if new[c2][2]==c[2] and new[c2][0]==c[0]:
if new[c2][2]==c[2] and (new[c2][0] == c[0] \
or getattr(new[c2][0],'__name__', True) == \
getattr(c[0],'__name__', False)):
# If new class defines a constraint with
# same function name, we let it override
# the old one.
new[c2] = c
exist = True
break