[FIX] addons: fix usage of decorators `api.v7`/`api.v8`
Specifically, when one API implementation calls the other one, it has to call the method *from the same class*. Otherwise, overriding the method may result in an infinite recursion. Consider: class A(Model): _name = 'stuff' @api.v8 def foo(self): return 42 @api.v7 def foo(self, cr, uid, context=None): return self.browse(cr, uid, [], context).foo() class B(Model): _inherit = 'stuff' def foo(self, cr, uid, context=None): return super(B, self).foo(cr, uid, context=context) + 1 and now call: `env['stuff'].foo()`. This invokes `B.foo` (new-API), which calls `B.foo` (old-API), which calls `A.foo` (old-API), which calls `B.foo` (new-API) instead of `A.foo`! This issue would not be present if old-API `A.foo` was defined as: @api.v7 def foo(self, cr, uid, context=None): return A.foo(self.browse(cr, uid, [], context))
This commit is contained in:
parent
d82e489add
commit
5763c32a6d
|
@ -2141,8 +2141,8 @@ class account_tax(osv.osv):
|
|||
|
||||
@api.v8
|
||||
def compute_all(self, price_unit, quantity, product=None, partner=None, force_excluded=False):
|
||||
return self._model.compute_all(
|
||||
self._cr, self._uid, self, price_unit, quantity,
|
||||
return account_tax.compute_all(
|
||||
self._model, self._cr, self._uid, self, price_unit, quantity,
|
||||
product=product, partner=partner, force_excluded=force_excluded)
|
||||
|
||||
def compute(self, cr, uid, taxes, price_unit, quantity, product=None, partner=None):
|
||||
|
|
|
@ -1209,7 +1209,7 @@ class account_invoice(models.Model):
|
|||
def pay_and_reconcile(self, cr, uid, ids, pay_amount, pay_account_id, period_id, pay_journal_id,
|
||||
writeoff_acc_id, writeoff_period_id, writeoff_journal_id, context=None, name=''):
|
||||
recs = self.browse(cr, uid, ids, context)
|
||||
return recs.pay_and_reconcile(pay_amount, pay_account_id, period_id, pay_journal_id,
|
||||
return account_invoice.pay_and_reconcile(recs, pay_amount, pay_account_id, period_id, pay_journal_id,
|
||||
writeoff_acc_id, writeoff_period_id, writeoff_journal_id, name=name)
|
||||
|
||||
class account_invoice_line(models.Model):
|
||||
|
@ -1600,7 +1600,7 @@ class account_invoice_tax(models.Model):
|
|||
def compute(self, cr, uid, invoice_id, context=None):
|
||||
recs = self.browse(cr, uid, [], context)
|
||||
invoice = recs.env['account.invoice'].browse(invoice_id)
|
||||
return recs.compute(invoice)
|
||||
return account_invoice_tax.compute(recs, invoice)
|
||||
|
||||
@api.model
|
||||
def move_line_get(self, invoice_id):
|
||||
|
|
|
@ -177,8 +177,8 @@ class Report(osv.Model):
|
|||
|
||||
@api.v8
|
||||
def get_html(self, records, report_name, data=None):
|
||||
return self._model.get_html(self._cr, self._uid, records.ids, report_name,
|
||||
data=data, context=self._context)
|
||||
return Report.get_html(self._model, self._cr, self._uid, records.ids,
|
||||
report_name, data=data, context=self._context)
|
||||
|
||||
@api.v7
|
||||
def get_pdf(self, cr, uid, ids, report_name, html=None, data=None, context=None):
|
||||
|
@ -276,8 +276,8 @@ class Report(osv.Model):
|
|||
|
||||
@api.v8
|
||||
def get_pdf(self, records, report_name, html=None, data=None):
|
||||
return self._model.get_pdf(self._cr, self._uid, records.ids, report_name,
|
||||
html=html, data=data, context=self._context)
|
||||
return Report.get_pdf(self._model, self._cr, self._uid, records.ids,
|
||||
report_name, html=html, data=data, context=self._context)
|
||||
|
||||
@api.v7
|
||||
def get_action(self, cr, uid, ids, report_name, data=None, context=None):
|
||||
|
@ -313,8 +313,8 @@ class Report(osv.Model):
|
|||
|
||||
@api.v8
|
||||
def get_action(self, records, report_name, data=None):
|
||||
return self._model.get_action(self._cr, self._uid, records.ids, report_name,
|
||||
data=data, context=self._context)
|
||||
return Report.get_action(self._model, self._cr, self._uid, records.ids,
|
||||
report_name, data=data, context=self._context)
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
# Report generation helpers
|
||||
|
@ -360,8 +360,8 @@ class Report(osv.Model):
|
|||
|
||||
@api.v8
|
||||
def _check_attachment_use(self, records, report):
|
||||
return self._model._check_attachment_use(
|
||||
self._cr, self._uid, records.ids, report, context=self._context)
|
||||
return Report._check_attachment_use(
|
||||
self._model, self._cr, self._uid, records.ids, report, context=self._context)
|
||||
|
||||
def _check_wkhtmltopdf(self):
|
||||
return wkhtmltopdf_state
|
||||
|
|
|
@ -608,6 +608,16 @@ def v7(method_v7):
|
|||
def foo(self):
|
||||
...
|
||||
|
||||
Special care must be taken if one method calls the other one, because
|
||||
the method may be overridden! In that case, one should call the method
|
||||
from the current class (say ``MyClass``), for instance::
|
||||
|
||||
@api.v7
|
||||
def foo(self, cr, uid, ids, context=None):
|
||||
# Beware: records.foo() may call an overriding of foo()
|
||||
records = self.browse(cr, uid, ids, context)
|
||||
return MyClass.foo(records)
|
||||
|
||||
Note that the wrapper method uses the docstring of the first method.
|
||||
"""
|
||||
# retrieve method_v8 from the caller's frame
|
||||
|
|
Loading…
Reference in New Issue