diff --git a/addons/account/models/account_analytic_line.py b/addons/account/models/account_analytic_line.py index 92e3dc6c973..9a7235ac9a0 100644 --- a/addons/account/models/account_analytic_line.py +++ b/addons/account/models/account_analytic_line.py @@ -17,7 +17,6 @@ class AccountAnalyticLine(models.Model): code = fields.Char(size=8) ref = fields.Char(string='Ref.') - @api.v8 @api.onchange('product_id', 'product_uom_id', 'unit_amount', 'currency_id') def on_change_unit_amount(self): if not self.product_id: diff --git a/addons/account/models/account_move.py b/addons/account/models/account_move.py index f69db68a67f..1309145169c 100644 --- a/addons/account/models/account_move.py +++ b/addons/account/models/account_move.py @@ -2779,7 +2779,6 @@ class AccountMoveLine(models.Model): # LOW-LEVEL METHODS # ------------------------------------------------------------------------- - @api.model_cr def init(self): """ change index on partner_id to a multi-column index on (partner_id, ref), the new index will behave in the same way when we search on partner_id, with the addition of being optimal when having a query that will diff --git a/addons/account/report/account_invoice_report.py b/addons/account/report/account_invoice_report.py index d63c997347f..1ac06b0372d 100644 --- a/addons/account/report/account_invoice_report.py +++ b/addons/account/report/account_invoice_report.py @@ -164,7 +164,6 @@ class AccountInvoiceReport(models.Model): COALESCE(partner.country_id, commercial_partner.country_id) ''' - @api.model_cr def init(self): tools.drop_view_if_exists(self.env.cr, self._table) self.env.cr.execute(''' diff --git a/addons/base_automation/models/base_automation.py b/addons/base_automation/models/base_automation.py index ba754f2fe3e..ea7c204a1a5 100644 --- a/addons/base_automation/models/base_automation.py +++ b/addons/base_automation/models/base_automation.py @@ -231,7 +231,6 @@ class BaseAutomation(models.Model): ) return any(differ(field.name) for field in self.trigger_field_ids) - @api.model_cr def _register_hook(self): """ Patch models that should trigger action rules based on creation, modification, deletion of records and form onchanges. diff --git a/addons/base_gengo/wizard/base_gengo_translations.py b/addons/base_gengo/wizard/base_gengo_translations.py index e7f806074b4..b6b2c4966a4 100644 --- a/addons/base_gengo/wizard/base_gengo_translations.py +++ b/addons/base_gengo/wizard/base_gengo_translations.py @@ -45,13 +45,11 @@ class BaseGengoTranslations(models.TransientModel): sync_limit = fields.Integer("No. of terms to sync", default=20) authorized_credentials = fields.Boolean('The private and public keys are valid') - @api.model_cr def init(self): icp = self.env['ir.config_parameter'].sudo() if not icp.get_param(self.GENGO_KEY): icp.set_param(self.GENGO_KEY, str(uuid.uuid4())) - @api.model_cr def get_gengo_key(self): icp = self.env['ir.config_parameter'].sudo() return icp.get_param(self.GENGO_KEY, default="Undefined") diff --git a/addons/crm/models/crm_lead.py b/addons/crm/models/crm_lead.py index 483917ccf92..fab4eef4d45 100644 --- a/addons/crm/models/crm_lead.py +++ b/addons/crm/models/crm_lead.py @@ -57,7 +57,6 @@ class Lead(models.Model): 'utm.mixin', 'format.address.mixin', 'phone.validation.mixin'] _primary_email = 'email_from' - @api.model_cr_context def _auto_init(self): res = super(Lead, self)._auto_init() tools.create_index(self._cr, 'crm_lead_create_date_team_id_idx', @@ -146,7 +145,6 @@ class Lead(models.Model): ('check_probability', 'check(probability >= 0 and probability <= 100)', 'The probability of closing the deal should be between 0% and 100%!') ] - @api.model_cr_context def _auto_init(self): res = super(Lead, self)._auto_init() tools.create_index(self._cr, 'crm_lead_user_id_team_id_type_index', diff --git a/addons/crm/report/crm_activity_report.py b/addons/crm/report/crm_activity_report.py index 55742b22623..554b49a3290 100644 --- a/addons/crm/report/crm_activity_report.py +++ b/addons/crm/report/crm_activity_report.py @@ -75,7 +75,6 @@ class ActivityReport(models.Model): m.model = 'crm.lead' AND (m.mail_activity_type_id IS NOT NULL OR m.subtype_id = %s) """ % (disccusion_subtype.id,) - @api.model_cr def init(self): tools.drop_view_if_exists(self._cr, self._table) self._cr.execute(""" diff --git a/addons/crm_iap_lead_website/models/crm_reveal_view.py b/addons/crm_iap_lead_website/models/crm_reveal_view.py index fb0705adcdc..a8a7dd14a7c 100644 --- a/addons/crm_iap_lead_website/models/crm_reveal_view.py +++ b/addons/crm_iap_lead_website/models/crm_reveal_view.py @@ -17,7 +17,6 @@ class CRMRevealView(models.Model): reveal_state = fields.Selection([('to_process', 'To Process'), ('not_found', 'Not Found')], default='to_process', string="State", index=True) create_date = fields.Datetime(index=True) - @api.model_cr def init(self): self._cr.execute('SELECT indexname FROM pg_indexes WHERE indexname = %s', ('crm_reveal_view_ip_rule_id',)) if not self._cr.fetchone(): diff --git a/addons/hr/models/hr_employee_public.py b/addons/hr/models/hr_employee_public.py index 82799661d0e..1f7af77dfb9 100644 --- a/addons/hr/models/hr_employee_public.py +++ b/addons/hr/models/hr_employee_public.py @@ -49,7 +49,6 @@ class HrEmployeePublic(models.Model): def _get_fields(self): return ','.join('emp.%s' % name for name, field in self._fields.items() if field.store and field.type not in ['many2many', 'one2many']) - @api.model_cr def init(self): tools.drop_view_if_exists(self.env.cr, self._table) self.env.cr.execute("""CREATE or REPLACE VIEW %s as ( diff --git a/addons/hr_holidays/models/hr_leave.py b/addons/hr_holidays/models/hr_leave.py index f4223cdddeb..12c44f26cb4 100644 --- a/addons/hr_holidays/models/hr_leave.py +++ b/addons/hr_holidays/models/hr_leave.py @@ -252,7 +252,6 @@ class HolidaysRequest(models.Model): ('duration_check', "CHECK ( number_of_days >= 0 )", "If you want to change the number of days you should use the 'period' mode"), ] - @api.model_cr_context def _auto_init(self): res = super(HolidaysRequest, self)._auto_init() tools.create_index(self._cr, 'hr_leave_date_to_date_from_index', diff --git a/addons/hr_timesheet_attendance/report/hr_timesheet_attendance_report.py b/addons/hr_timesheet_attendance/report/hr_timesheet_attendance_report.py index 0aa0bbaf275..7081a1ac5af 100644 --- a/addons/hr_timesheet_attendance/report/hr_timesheet_attendance_report.py +++ b/addons/hr_timesheet_attendance/report/hr_timesheet_attendance_report.py @@ -15,7 +15,6 @@ class TimesheetAttendance(models.Model): total_attendance = fields.Float() total_difference = fields.Float() - @api.model_cr def init(self): self._cr.execute("""CREATE OR REPLACE VIEW %s AS ( SELECT diff --git a/addons/im_livechat/report/im_livechat_report_channel.py b/addons/im_livechat/report/im_livechat_report_channel.py index 21305ab7b99..70b1fc1d30f 100644 --- a/addons/im_livechat/report/im_livechat_report_channel.py +++ b/addons/im_livechat/report/im_livechat_report_channel.py @@ -38,7 +38,6 @@ class ImLivechatReportChannel(models.Model): is_unrated = fields.Integer('Session not rated', readonly=True) partner_id = fields.Many2one('res.partner', 'Operator', readonly=True) - @api.model_cr def init(self): # Note : start_date_hour must be remove when the read_group will allow grouping on the hour of a datetime. Don't forget to change the view ! tools.drop_view_if_exists(self.env.cr, 'im_livechat_report_channel') diff --git a/addons/im_livechat/report/im_livechat_report_operator.py b/addons/im_livechat/report/im_livechat_report_operator.py index a9391e2a6be..cafaf898da2 100644 --- a/addons/im_livechat/report/im_livechat_report_operator.py +++ b/addons/im_livechat/report/im_livechat_report_operator.py @@ -20,7 +20,6 @@ class ImLivechatReportOperator(models.Model): time_to_answer = fields.Float('Time to answer', digits=(16, 2), readonly=True, group_operator="avg", help="Average time to give the first answer to the visitor") duration = fields.Float('Average duration', digits=(16, 2), readonly=True, group_operator="avg", help="Duration of the conversation (in seconds)") - @api.model_cr def init(self): # Note : start_date_hour must be remove when the read_group will allow grouping on the hour of a datetime. Don't forget to change the view ! tools.drop_view_if_exists(self.env.cr, 'im_livechat_report_operator') diff --git a/addons/l10n_in/report/account_invoice_report.py b/addons/l10n_in/report/account_invoice_report.py index ebbee57ab68..d33d1927e78 100644 --- a/addons/l10n_in/report/account_invoice_report.py +++ b/addons/l10n_in/report/account_invoice_report.py @@ -302,7 +302,6 @@ class L10nInAccountInvoiceReport(models.Model): """ return group_by_str - @api.model_cr def init(self): tools.drop_view_if_exists(self.env.cr, self._table) self.env.cr.execute("""CREATE or REPLACE VIEW %s AS ( diff --git a/addons/l10n_in/report/account_payment_report.py b/addons/l10n_in/report/account_payment_report.py index 266d8f39c43..05aed203314 100644 --- a/addons/l10n_in/report/account_payment_report.py +++ b/addons/l10n_in/report/account_payment_report.py @@ -101,7 +101,6 @@ class L10nInPaymentReport(models.AbstractModel): AND tax.tax_group_id in (SELECT res_id FROM ir_model_data WHERE module='l10n_in' AND name in ('igst_group','gst_group')) AND ac.internal_type IN ('receivable', 'payable') AND am.state = 'posted'""" - @api.model_cr def init(self): tools.drop_view_if_exists(self.env.cr, self._table) self.env.cr.execute("""CREATE or REPLACE VIEW %s AS ( diff --git a/addons/l10n_in/report/exempted_gst_report.py b/addons/l10n_in/report/exempted_gst_report.py index 05d68a39ded..435b58e05cf 100644 --- a/addons/l10n_in/report/exempted_gst_report.py +++ b/addons/l10n_in/report/exempted_gst_report.py @@ -89,7 +89,6 @@ class L10nInExemptedReport(models.Model): """ return from_str - @api.model_cr def init(self): tools.drop_view_if_exists(self.env.cr, self._table) self._cr.execute("""CREATE OR REPLACE VIEW %s AS (%s %s)""" % ( diff --git a/addons/l10n_in/report/hsn_gst_report.py b/addons/l10n_in/report/hsn_gst_report.py index 0fb4a844a74..7961ddda02b 100644 --- a/addons/l10n_in/report/hsn_gst_report.py +++ b/addons/l10n_in/report/hsn_gst_report.py @@ -98,7 +98,6 @@ class L10nInProductHsnReport(models.Model): """ return from_str - @api.model_cr def init(self): tools.drop_view_if_exists(self.env.cr, self._table) self.env.cr.execute("""CREATE OR REPLACE VIEW %s AS (%s %s)""" % ( diff --git a/addons/mail/models/mail_alias.py b/addons/mail/models/mail_alias.py index 77bdc216728..ecf03c3c5a3 100644 --- a/addons/mail/models/mail_alias.py +++ b/addons/mail/models/mail_alias.py @@ -220,7 +220,6 @@ class AliasMixin(models.AbstractModel): aliases.unlink() return res - @api.model_cr_context def _init_column(self, name): """ Create aliases for existing rows. """ super(AliasMixin, self)._init_column(name) diff --git a/addons/mail/models/mail_channel.py b/addons/mail/models/mail_channel.py index 524f3763d93..7912a856ca4 100644 --- a/addons/mail/models/mail_channel.py +++ b/addons/mail/models/mail_channel.py @@ -410,7 +410,6 @@ class Channel(models.Model): return True return super(Channel, self)._alias_check_contact(message, message_dict, alias) - @api.model_cr def init(self): self._cr.execute('SELECT indexname FROM pg_indexes WHERE indexname = %s', ('mail_channel_partner_seen_message_id_idx',)) if not self._cr.fetchone(): diff --git a/addons/mail/models/mail_message.py b/addons/mail/models/mail_message.py index 1b9e8b41fa4..e90249e9533 100644 --- a/addons/mail/models/mail_message.py +++ b/addons/mail/models/mail_message.py @@ -585,7 +585,6 @@ class Message(models.Model): # mail_message internals #------------------------------------------------------ - @api.model_cr def init(self): self._cr.execute("""SELECT indexname FROM pg_indexes WHERE indexname = 'mail_message_model_res_id_idx'""") if not self._cr.fetchone(): diff --git a/addons/mail/models/mail_notification.py b/addons/mail/models/mail_notification.py index b687633a86d..3397342a818 100644 --- a/addons/mail/models/mail_notification.py +++ b/addons/mail/models/mail_notification.py @@ -37,7 +37,6 @@ class Notification(models.Model): ], string='Failure type') failure_reason = fields.Text('Failure reason', copy=False) - @api.model_cr def init(self): self._cr.execute('SELECT indexname FROM pg_indexes WHERE indexname = %s', ('mail_notification_res_partner_id_is_read_email_status_mail_message_id',)) if not self._cr.fetchone(): diff --git a/addons/mail/wizard/mail_compose_message.py b/addons/mail/wizard/mail_compose_message.py index f5ad45c0a56..e88c11cbc84 100644 --- a/addons/mail/wizard/mail_compose_message.py +++ b/addons/mail/wizard/mail_compose_message.py @@ -430,9 +430,6 @@ class MailComposer(models.TransientModel): values['body'] = values.pop('body_html') # This onchange should return command instead of ids for x2many field. - # ORM handle the assignation of command list on new onchange (api.v8), - # this force the complete replacement of x2many field with - # command and is compatible with onchange api.v7 values = self._convert_to_write(values) return {'value': values} diff --git a/addons/mass_mailing/models/mass_mailing_report.py b/addons/mass_mailing/models/mass_mailing_report.py index 13f8c873d6e..de63344389c 100644 --- a/addons/mass_mailing/models/mass_mailing_report.py +++ b/addons/mass_mailing/models/mass_mailing_report.py @@ -22,7 +22,6 @@ class MassMailingReport(models.Model): string='Status', readonly=True) email_from = fields.Char('From', readonly=True) - @api.model_cr def init(self): """Mass Mail Statistical Report: based on mail.mail.statistics that models the various statistics collected for each mailing, and mail.mass_mailing model that models the diff --git a/addons/membership/report/report_membership.py b/addons/membership/report/report_membership.py index 1734bc045f5..bab4b67a7b1 100644 --- a/addons/membership/report/report_membership.py +++ b/addons/membership/report/report_membership.py @@ -37,7 +37,6 @@ class ReportMembership(models.Model): company_id = fields.Many2one('res.company', string='Company', readonly=True) quantity = fields.Integer(readonly=True) - @api.model_cr def init(self): '''Create the view''' tools.drop_view_if_exists(self._cr, self._table) diff --git a/addons/point_of_sale/report/pos_order_report.py b/addons/point_of_sale/report/pos_order_report.py index 3111dc7fd3c..33684c818c7 100644 --- a/addons/point_of_sale/report/pos_order_report.py +++ b/addons/point_of_sale/report/pos_order_report.py @@ -94,7 +94,6 @@ class PosOrderReport(models.Model): SUM(l.qty * u.factor) != 0 """ - @api.model_cr def init(self): tools.drop_view_if_exists(self._cr, self._table) self._cr.execute(""" diff --git a/addons/purchase/report/purchase_bill.py b/addons/purchase/report/purchase_bill.py index 0a9609144b8..8517cc6ad5b 100644 --- a/addons/purchase/report/purchase_bill.py +++ b/addons/purchase/report/purchase_bill.py @@ -20,7 +20,6 @@ class PurchaseBillUnion(models.Model): vendor_bill_id = fields.Many2one('account.move', string='Vendor Bill', readonly=True) purchase_order_id = fields.Many2one('purchase.order', string='Purchase Order', readonly=True) - @api.model_cr def init(self): tools.drop_view_if_exists(self.env.cr, 'purchase_bill_union') self.env.cr.execute(""" diff --git a/addons/purchase/report/purchase_report.py b/addons/purchase/report/purchase_report.py index d3a04e7d06e..1385d7c12bd 100644 --- a/addons/purchase/report/purchase_report.py +++ b/addons/purchase/report/purchase_report.py @@ -50,7 +50,6 @@ class PurchaseReport(models.Model): qty_billed = fields.Float('Qty Billed', readonly=True) qty_to_be_billed = fields.Float('Qty to be Billed', readonly=True) - @api.model_cr def init(self): # self._table = sale_report tools.drop_view_if_exists(self.env.cr, self._table) diff --git a/addons/sale/report/report_all_channels_sales.py b/addons/sale/report/report_all_channels_sales.py index 473ab1f1362..1aa6e96006d 100644 --- a/addons/sale/report/report_all_channels_sales.py +++ b/addons/sale/report/report_all_channels_sales.py @@ -82,7 +82,6 @@ class PosSaleReport(models.Model): AS foo""" % (self._table, self._from()) return request - @api.model_cr def init(self): tools.drop_view_if_exists(self.env.cr, self._table) self.env.cr.execute(self.get_main_request()) diff --git a/addons/sale/report/sale_report.py b/addons/sale/report/sale_report.py index 4936a9401ed..e1fa1ce8620 100644 --- a/addons/sale/report/sale_report.py +++ b/addons/sale/report/sale_report.py @@ -144,7 +144,6 @@ class SaleReport(models.Model): return '%s (SELECT %s FROM %s WHERE l.product_id IS NOT NULL GROUP BY %s)' % (with_, select_, from_, groupby_) - @api.model_cr def init(self): # self._table = sale_report tools.drop_view_if_exists(self.env.cr, self._table) diff --git a/addons/stock/models/stock_move.py b/addons/stock/models/stock_move.py index 531324a45c0..14e62ac4e58 100644 --- a/addons/stock/models/stock_move.py +++ b/addons/stock/models/stock_move.py @@ -354,7 +354,6 @@ class StockMove(models.Model): user_warning += _('\n\nBlocking: %s') % ' ,'.join(moves_error.mapped('name')) raise UserError(user_warning) - @api.model_cr def init(self): self._cr.execute('SELECT indexname FROM pg_indexes WHERE indexname = %s', ('stock_move_product_location_index',)) if not self._cr.fetchone(): diff --git a/addons/stock/report/report_stock_forecast.py b/addons/stock/report/report_stock_forecast.py index 1bf69ab5719..b3cca6a6ecb 100644 --- a/addons/stock/report/report_stock_forecast.py +++ b/addons/stock/report/report_stock_forecast.py @@ -17,7 +17,6 @@ class ReportStockForecat(models.Model): picking_id = fields.Many2one('stock.picking', string='Picking', readonly=True) reference = fields.Char('Reference') - @api.model_cr def init(self): tools.drop_view_if_exists(self._cr, 'report_stock_forecast') query = """ diff --git a/addons/website/models/res_users.py b/addons/website/models/res_users.py index 8902e4c34b6..c5fb684888c 100644 --- a/addons/website/models/res_users.py +++ b/addons/website/models/res_users.py @@ -47,7 +47,6 @@ class ResUsers(models.Model): current_website = self.env['website'].get_current_website() return current_website.auth_signup_uninvited or super(ResUsers, self)._get_signup_invitation_scope() - @api.model_cr_context def _auto_init(self): result = super(ResUsers, self)._auto_init() # Use unique index to implement unique constraint per website, even if website_id is null diff --git a/addons/website_crm_partner_assign/report/crm_partner_report.py b/addons/website_crm_partner_assign/report/crm_partner_report.py index d78f1b1dd67..05043f7b313 100644 --- a/addons/website_crm_partner_assign/report/crm_partner_report.py +++ b/addons/website_crm_partner_assign/report/crm_partner_report.py @@ -30,7 +30,6 @@ class CrmPartnerReportAssign(models.Model): 'grade_id', 'parent_id', 'team_id', 'user_id'], } - @api.model_cr def init(self): """ CRM Lead Report diff --git a/addons/website_event_questions/report/report_event_registrations_questions.py b/addons/website_event_questions/report/report_event_registrations_questions.py index 8d229c55469..6bbd52d043f 100644 --- a/addons/website_event_questions/report/report_event_registrations_questions.py +++ b/addons/website_event_questions/report/report_event_registrations_questions.py @@ -14,7 +14,6 @@ class ReportEventRegistrationQuestions(models.Model): answer_id = fields.Many2one(comodel_name='event.answer', string='Answer') event_id = fields.Many2one(comodel_name='event.event', string='Event') - @api.model_cr def init(self): """ Event Question main report """ tools.drop_view_if_exists(self._cr, 'event_question_report') diff --git a/addons/website_form/models/models.py b/addons/website_form/models/models.py index 8f7f148de75..c3755143daa 100644 --- a/addons/website_form/models/models.py +++ b/addons/website_form/models/models.py @@ -79,7 +79,6 @@ class website_form_model_fields(models.Model): _description = 'Fields' _inherit = 'ir.model.fields' - @api.model_cr def init(self): # set all existing unset website_form_blacklisted fields to ``true`` # (so that we can use it as a whitelist rather than a blacklist) diff --git a/addons/website_slides/models/slide_channel.py b/addons/website_slides/models/slide_channel.py index c157f692599..d3614c4a845 100644 --- a/addons/website_slides/models/slide_channel.py +++ b/addons/website_slides/models/slide_channel.py @@ -294,7 +294,6 @@ class Channel(models.Model): # ORM Overrides # --------------------------------------------------------- - @api.model_cr_context def _init_column(self, column_name): """ Initialize the value of the given column for existing rows. Overridden here because we need to generate different access tokens diff --git a/doc/reference/orm.rst b/doc/reference/orm.rst index f0c0452c8d5..20440d5c414 100644 --- a/doc/reference/orm.rst +++ b/doc/reference/orm.rst @@ -1205,20 +1205,6 @@ Porting from the old API to the new API :attr:`~odoo.models.Model.write_date` fields: they are now created as regular "legitimate" fields, and can be read and written like any other field out-of-the-box -* when straight conversion is impossible (semantics can not be bridged) or the - "old API" version is not desirable and could be improved for the new API, it - is possible to use completely different "old API" and "new API" - implementations for the same method name using :func:`~odoo.api.v7` and - :func:`~odoo.api.v8`. The method should first be defined using the - old-API style and decorated with :func:`~odoo.api.v7`, it should then be - re-defined using the exact same name but the new-API style and decorated - with :func:`~odoo.api.v8`. Calls from an old-API context will be - dispatched to the first implementation and calls from a new-API context will - be dispatched to the second implementation. One implementation can call (and - frequently does) call the other by switching context. - - .. danger:: using these decorators makes methods extremely difficult to - override and harder to understand and document * uses of :attr:`~odoo.models.Model._columns` or :attr:`~odoo.models.Model._all_columns` should be replaced by :attr:`~odoo.models.Model._fields`, which provides access to instances of @@ -1277,28 +1263,3 @@ decorating the old-style method: * disabling it entirely, by decorating a method with :func:`~odoo.api.noguess` there will be no bridging and methods will be called the exact same way from the new and old API styles -* defining the bridge explicitly, this is mostly for methods which are matched - incorrectly (because parameters are named in unexpected ways): - - :func:`~odoo.api.cr` - will automatically prepend the current cursor to explicitly provided - parameters, positionally - :func:`~odoo.api.cr_uid` - will automatically prepend the current cursor and user's id to explictly - provided parameters - :func:`~odoo.api.cr_uid_ids` - will automatically prepend the current cursor, user's id and recordset's - ids to explicitly provided parameters - :func:`~odoo.api.cr_uid_id` - will loop over the current recordset and call the method once for each - record, prepending the current cursor, user's id and record's id to - explicitly provided parameters. - - .. danger:: the result of this wrapper is *always a list* when calling - from a new-API context - - All of these methods have a ``_context``-suffixed version - (e.g. :func:`~odoo.api.cr_uid_context`) which also passes the current - context *by keyword*. -* dual implementations using :func:`~odoo.api.v7` and - :func:`~odoo.api.v8` will be ignored as they provide their own "bridging" diff --git a/odoo/addons/base/models/decimal_precision.py b/odoo/addons/base/models/decimal_precision.py index 9d1e67a22b3..dec400b1328 100644 --- a/odoo/addons/base/models/decimal_precision.py +++ b/odoo/addons/base/models/decimal_precision.py @@ -32,11 +32,6 @@ class DecimalPrecision(models.Model): res = self.env.cr.fetchone() return res[0] if res else 2 - @api.model_cr - def clear_cache(self): - """ Deprecated, use `clear_caches` instead. """ - self.clear_caches() - @api.model_create_multi def create(self, vals_list): res = super(DecimalPrecision, self).create(vals_list) diff --git a/odoo/addons/base/models/ir_actions.py b/odoo/addons/base/models/ir_actions.py index 94d1abbd940..66d11d4bd6e 100644 --- a/odoo/addons/base/models/ir_actions.py +++ b/odoo/addons/base/models/ir_actions.py @@ -283,7 +283,6 @@ class IrActionsActWindowView(models.Model): act_window_id = fields.Many2one('ir.actions.act_window', string='Action', ondelete='cascade') multi = fields.Boolean(string='On Multiple Doc.', help="If set to true, the action will not be displayed on the right toolbar of a form view.") - @api.model_cr_context def _auto_init(self): res = super(IrActionsActWindowView, self)._auto_init() tools.create_unique_index(self._cr, 'act_window_view_unique_mode_per_action', diff --git a/odoo/addons/base/models/ir_actions_report.py b/odoo/addons/base/models/ir_actions_report.py index 51ef9b9e32b..22807bdb6a0 100644 --- a/odoo/addons/base/models/ir_actions_report.py +++ b/odoo/addons/base/models/ir_actions_report.py @@ -765,7 +765,6 @@ class IrActionsReport(models.Model): return None return render_func(res_ids, data=data) - @api.noguess def report_action(self, docids, data=None, config=True): """Return an action of type ir.actions.report. diff --git a/odoo/addons/base/models/ir_attachment.py b/odoo/addons/base/models/ir_attachment.py index 734be5f88e9..8b191edb210 100644 --- a/odoo/addons/base/models/ir_attachment.py +++ b/odoo/addons/base/models/ir_attachment.py @@ -300,7 +300,6 @@ class IrAttachment(models.Model): mimetype = fields.Char('Mime Type', readonly=True) index_content = fields.Text('Indexed Content', readonly=True, prefetch=False) - @api.model_cr_context def _auto_init(self): res = super(IrAttachment, self)._auto_init() tools.create_index(self._cr, 'ir_attachment_res_idx', diff --git a/odoo/addons/base/models/ir_config_parameter.py b/odoo/addons/base/models/ir_config_parameter.py index 75be28c9359..32e7a838854 100644 --- a/odoo/addons/base/models/ir_config_parameter.py +++ b/odoo/addons/base/models/ir_config_parameter.py @@ -39,7 +39,6 @@ class IrConfigParameter(models.Model): ('key_uniq', 'unique (key)', 'Key must be unique.') ] - @api.model_cr @mute_logger('odoo.addons.base.models.ir_config_parameter') def init(self, force=False): """ diff --git a/odoo/addons/base/models/ir_filters.py b/odoo/addons/base/models/ir_filters.py index 547302be38b..75845870224 100644 --- a/odoo/addons/base/models/ir_filters.py +++ b/odoo/addons/base/models/ir_filters.py @@ -150,7 +150,6 @@ class IrFilters(models.Model): ('name_model_uid_unique', 'unique (name, model_id, user_id, action_id)', 'Filter names must be unique'), ] - @api.model_cr_context def _auto_init(self): result = super(IrFilters, self)._auto_init() # Use unique index to implement unique constraint on the lowercase name (not possible using a constraint) diff --git a/odoo/addons/base/models/ir_logging.py b/odoo/addons/base/models/ir_logging.py index 30fcaf3bd1d..567b95264d2 100644 --- a/odoo/addons/base/models/ir_logging.py +++ b/odoo/addons/base/models/ir_logging.py @@ -32,7 +32,6 @@ class IrLogging(models.Model): func = fields.Char(string='Function', required=True) line = fields.Char(required=True) - @api.model_cr def init(self): super(IrLogging, self).init() self._cr.execute("select 1 from information_schema.constraint_column_usage where table_name = 'ir_logging' and constraint_name = 'ir_logging_write_uid_fkey'") diff --git a/odoo/addons/base/models/ir_model.py b/odoo/addons/base/models/ir_model.py index a0337f85182..269091f2843 100644 --- a/odoo/addons/base/models/ir_model.py +++ b/odoo/addons/base/models/ir_model.py @@ -1191,7 +1191,7 @@ class IrModelAccess(models.Model): self._cr.execute(query, (model_name, tuple(group_ids))) return bool(self._cr.rowcount) - @api.model_cr + @api.model def group_names_with_access(self, model_name, access_mode): """ Return the names of visible groups which have been granted ``access_mode`` on the model ``model_name``. @@ -1288,7 +1288,7 @@ class IrModelAccess(models.Model): def unregister_cache_clearing_method(cls, model, method): cls.__cache_clearing_methods.discard((model, method)) - @api.model_cr + @api.model def call_cache_clearing_methods(self): self.invalidate_cache() self.check.clear_cache(self) # clear the cache of check function @@ -1352,7 +1352,6 @@ class IrModelData(models.Model): for res in self: res.reference = "%s,%s" % (res.model, res.res_id) - @api.model_cr_context def _auto_init(self): res = super(IrModelData, self)._auto_init() tools.create_unique_index(self._cr, 'ir_model_data_module_name_uniq_index', diff --git a/odoo/addons/base/models/ir_translation.py b/odoo/addons/base/models/ir_translation.py index 373e5f5e8b0..b4fcfc1481f 100644 --- a/odoo/addons/base/models/ir_translation.py +++ b/odoo/addons/base/models/ir_translation.py @@ -247,7 +247,6 @@ class IrTranslation(models.Model): ''' the source term is stored on 'src' field ''' return [('src', operator, value)] - @api.model_cr_context def _auto_init(self): res = super(IrTranslation, self)._auto_init() # Add separate md5 index on src (no size limit on values, and good performance). @@ -759,7 +758,6 @@ class IrTranslation(models.Model): """ Return a cursor-like object for fast inserting translations """ return IrTranslationImport(self) - @api.model_cr_context def load_module_terms(self, modules, langs): """ Load PO files of the given modules for the given languages. """ # make sure the given languages are active diff --git a/odoo/addons/base/models/ir_ui_view.py b/odoo/addons/base/models/ir_ui_view.py index 622f4de1645..8a8d88bc17a 100644 --- a/odoo/addons/base/models/ir_ui_view.py +++ b/odoo/addons/base/models/ir_ui_view.py @@ -101,7 +101,6 @@ class ViewCustom(models.Model): return self.browse(view_ids).name_get() return super(ViewCustom, self)._name_search(name, args=args, operator=operator, limit=limit, name_get_uid=name_get_uid) - @api.model_cr_context def _auto_init(self): res = super(ViewCustom, self)._auto_init() tools.create_index(self._cr, 'ir_ui_view_custom_user_id_ref_id', @@ -408,7 +407,6 @@ actual arch. "Invalid key: QWeb view should have a key"), ] - @api.model_cr_context def _auto_init(self): res = super(View, self)._auto_init() tools.create_index(self._cr, 'ir_ui_view_model_type_inherit_id', diff --git a/odoo/addons/base/models/res_company.py b/odoo/addons/base/models/res_company.py index 2b69228c655..fb9146aea6b 100644 --- a/odoo/addons/base/models/res_company.py +++ b/odoo/addons/base/models/res_company.py @@ -102,7 +102,6 @@ class Company(models.Model): ] - @api.model_cr def init(self): for company in self.search([('paperformat_id', '=', False)]): paperformat_euro = self.env.ref('base.paperformat_euro', False) diff --git a/odoo/addons/base/models/res_config.py b/odoo/addons/base/models/res_config.py index e5b584a5768..b8617a09d5a 100644 --- a/odoo/addons/base/models/res_config.py +++ b/odoo/addons/base/models/res_config.py @@ -695,7 +695,7 @@ class ResConfigSettings(models.TransientModel, ResConfigModuleInstallationMixin) model_name, field_name = full_field_name.rsplit('.', 1) return self.env[model_name].fields_get([field_name])[field_name]['string'] - @api.model_cr_context + @api.model def get_config_warning(self, msg): """ Helper: return a Warning exception with the given message where the %(field:xxx)s diff --git a/odoo/addons/base/models/res_lang.py b/odoo/addons/base/models/res_lang.py index 9e37a5b7963..6fcd82354b6 100644 --- a/odoo/addons/base/models/res_lang.py +++ b/odoo/addons/base/models/res_lang.py @@ -82,7 +82,6 @@ class Lang(models.Model): except Exception: raise ValidationError(warning) - @api.model_cr def _register_hook(self): # check that there is at least one active language if not self.search_count([]): diff --git a/odoo/addons/base/models/res_partner.py b/odoo/addons/base/models/res_partner.py index 1fdcd5afe5b..d6677b972ac 100644 --- a/odoo/addons/base/models/res_partner.py +++ b/odoo/addons/base/models/res_partner.py @@ -241,7 +241,6 @@ class Partner(models.Model): ('check_name', "CHECK( (type='contact' AND name IS NOT NULL) or (type!='contact') )", 'Contacts require a name.'), ] - @api.model_cr def init(self): self._cr.execute("""SELECT indexname FROM pg_indexes WHERE indexname = 'res_partner_vat_index'""") if not self._cr.fetchone(): diff --git a/odoo/addons/test_performance/models/models.py b/odoo/addons/test_performance/models/models.py index f1c51453b47..5874d0a784e 100644 --- a/odoo/addons/test_performance/models/models.py +++ b/odoo/addons/test_performance/models/models.py @@ -35,7 +35,6 @@ class LineModel(models.Model): base_id = fields.Many2one('test_performance.base', required=True, ondelete='cascade') value = fields.Integer() - @api.model_cr def init(self): # line values should be unique per "base" - useful for testing corner cases with unique lines tools.create_unique_index(self._cr, 'test_performance_line_uniq', self._table, ['base_id', 'value']) diff --git a/odoo/api.py b/odoo/api.py index 99fcdcaa6e2..ab96c9f64fd 100644 --- a/odoo/api.py +++ b/odoo/api.py @@ -33,14 +33,8 @@ __all__ = [ 'Environment', - 'Meta', 'guess', 'noguess', + 'Meta', 'model', 'multi', - 'model_cr', 'model_cr_context', - 'cr', 'cr_context', - 'cr_uid', 'cr_uid_context', - 'cr_uid_id', 'cr_uid_id_context', - 'cr_uid_ids', 'cr_uid_ids_context', - 'cr_uid_records', 'cr_uid_records_context', 'constrains', 'depends', 'onchange', 'returns', 'call_kw', ] @@ -48,7 +42,7 @@ __all__ = [ import logging from collections import defaultdict, Mapping from contextlib import contextmanager -from inspect import currentframe, getargspec +from inspect import getargspec from pprint import pformat from weakref import WeakSet @@ -69,12 +63,8 @@ _logger = logging.getLogger(__name__) # # On wrapping method only: # - method._api: decorator function, used for re-applying decorator -# - method._orig: original method # -WRAPPED_ATTRS = ('__module__', '__name__', '__doc__', '_constrains', - '_depends', '_onchange', '_returns', 'clear_cache') - INHERITED_ATTRS = ('_returns',) @@ -82,6 +72,7 @@ class Params(object): def __init__(self, args, kwargs): self.args = args self.kwargs = kwargs + def __str__(self): params = [] for arg in self.args: @@ -106,13 +97,6 @@ class Meta(type): # make the method inherit from decorators value = propagate(getattr(parent, key, None), value) - # guess calling convention if none is given - if not hasattr(value, '_api'): - try: - value = guess(value) - except TypeError: - pass - if (getattr(value, '_api', None) or '').startswith('cr'): _logger.warning("Deprecated method %s.%s in module %s", name, key, attrs.get('__module__')) @@ -324,50 +308,6 @@ def multi(method): return method -def model_cr(method): - """ Decorate a record-style method where ``self`` is a recordset, but its - contents is not relevant, only the model is. Such a method:: - - @api.model_cr - def method(self, args): - ... - - may be called in both record and traditional styles, like:: - - # recs = model.browse(cr, uid, ids, context) - recs.method(args) - - model.method(cr, args) - - Notice that no ``uid``, ``ids``, ``context`` are passed to the method in - the traditional style. - """ - method._api = 'model_cr' - return method - - -def model_cr_context(method): - """ Decorate a record-style method where ``self`` is a recordset, but its - contents is not relevant, only the model is. Such a method:: - - @api.model_cr_context - def method(self, args): - ... - - may be called in both record and traditional styles, like:: - - # recs = model.browse(cr, uid, ids, context) - recs.method(args) - - model.method(cr, args, context=context) - - Notice that no ``uid``, ``ids`` are passed to the method in the - traditional style. - """ - method._api = 'model_cr_context' - return method - - _create_logger = logging.getLogger(__name__ + '.create') @@ -412,252 +352,6 @@ def model_create_multi(method): return wrapper -def cr(method): - """ Decorate a traditional-style method that takes ``cr`` as a parameter. - Such a method may be called in both record and traditional styles, like:: - - # recs = model.browse(cr, uid, ids, context) - recs.method(args) - - model.method(cr, args) - """ - method._api = 'cr' - return method - - -def cr_context(method): - """ Decorate a traditional-style method that takes ``cr``, ``context`` as parameters. """ - method._api = 'cr_context' - return method - - -def cr_uid(method): - """ Decorate a traditional-style method that takes ``cr``, ``uid`` as parameters. """ - method._api = 'cr_uid' - return method - - -def cr_uid_context(method): - """ Decorate a traditional-style method that takes ``cr``, ``uid``, ``context`` as - parameters. Such a method may be called in both record and traditional - styles, like:: - - # recs = model.browse(cr, uid, ids, context) - recs.method(args) - - model.method(cr, uid, args, context=context) - """ - method._api = 'cr_uid_context' - return method - - -def cr_uid_id(method): - """ Decorate a traditional-style method that takes ``cr``, ``uid``, ``id`` as - parameters. Such a method may be called in both record and traditional - styles. In the record style, the method automatically loops on records. - """ - method._api = 'cr_uid_id' - return method - - -def cr_uid_id_context(method): - """ Decorate a traditional-style method that takes ``cr``, ``uid``, ``id``, - ``context`` as parameters. Such a method:: - - @api.cr_uid_id - def method(self, cr, uid, id, args, context=None): - ... - - may be called in both record and traditional styles, like:: - - # rec = model.browse(cr, uid, id, context) - rec.method(args) - - model.method(cr, uid, id, args, context=context) - """ - method._api = 'cr_uid_id_context' - return method - - -def cr_uid_ids(method): - """ Decorate a traditional-style method that takes ``cr``, ``uid``, ``ids`` as - parameters. Such a method may be called in both record and traditional - styles. - """ - method._api = 'cr_uid_ids' - return method - - -def cr_uid_ids_context(method): - """ Decorate a traditional-style method that takes ``cr``, ``uid``, ``ids``, - ``context`` as parameters. Such a method:: - - @api.cr_uid_ids_context - def method(self, cr, uid, ids, args, context=None): - ... - - may be called in both record and traditional styles, like:: - - # recs = model.browse(cr, uid, ids, context) - recs.method(args) - - model.method(cr, uid, ids, args, context=context) - - It is generally not necessary, see :func:`guess`. - """ - method._api = 'cr_uid_ids_context' - return method - - -def cr_uid_records(method): - """ Decorate a traditional-style method that takes ``cr``, ``uid``, a - recordset of model ``self`` as parameters. Such a method:: - - @api.cr_uid_records - def method(self, cr, uid, records, args): - ... - - may be called in both record and traditional styles, like:: - - # records = model.browse(cr, uid, ids, context) - records.method(args) - - model.method(cr, uid, records, args) - """ - method._api = 'cr_uid_records' - return method - - -def cr_uid_records_context(method): - """ Decorate a traditional-style method that takes ``cr``, ``uid``, a - recordset of model ``self``, ``context`` as parameters. Such a method:: - - @api.cr_uid_records_context - def method(self, cr, uid, records, args, context=None): - ... - - may be called in both record and traditional styles, like:: - - # records = model.browse(cr, uid, ids, context) - records.method(args) - - model.method(cr, uid, records, args, context=context) - """ - method._api = 'cr_uid_records_context' - return method - - -def v7(method_v7): - """ Decorate a method that supports the old-style api only. A new-style api - may be provided by redefining a method with the same name and decorated - with :func:`~.v8`:: - - @api.v7 - def foo(self, cr, uid, ids, context=None): - ... - - @api.v8 - 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 - frame = currentframe().f_back - return frame.f_locals.get(method_v7.__name__, method_v7) - - -def v8(method_v8): - """ Decorate a method that supports the new-style api only. An old-style api - may be provided by redefining a method with the same name and decorated - with :func:`~.v7`:: - - @api.v8 - def foo(self): - ... - - @api.v7 - def foo(self, cr, uid, ids, context=None): - ... - - Note that the wrapper method uses the docstring of the first method. - """ - if method_v8.__name__ == 'read': - return multi(method_v8) - method_v8._api = 'v8' - return method_v8 - - -def noguess(method): - """ Decorate a method to prevent any effect from :func:`guess`. """ - method._api = None - return method - - -def guess(method): - """ Decorate ``method`` to make it callable in both traditional and record - styles. This decorator is applied automatically by the model's - metaclass, and has no effect on already-decorated methods. - - The API style is determined by heuristics on the parameter names: ``cr`` - or ``cursor`` for the cursor, ``uid`` or ``user`` for the user id, - ``id`` or ``ids`` for a list of record ids, and ``context`` for the - context dictionary. If a traditional API is recognized, one of the - decorators :func:`cr`, :func:`cr_context`, :func:`cr_uid`, - :func:`cr_uid_context`, :func:`cr_uid_id`, :func:`cr_uid_id_context`, - :func:`cr_uid_ids`, :func:`cr_uid_ids_context` is applied on the method. - - Method calls are considered traditional style when their first parameter - is a database cursor. - """ - if hasattr(method, '_api'): - return method - - # introspection on argument names to determine api style - args, vname, kwname, defaults = getargspec(method) - names = tuple(args) + (None,) * 4 - - if names[0] == 'self': - if names[1] in ('cr', 'cursor'): - if names[2] in ('uid', 'user'): - if names[3] == 'ids': - if 'context' in names or kwname: - return cr_uid_ids_context(method) - else: - return cr_uid_ids(method) - elif names[3] == 'id' or names[3] == 'res_id': - if 'context' in names or kwname: - return cr_uid_id_context(method) - else: - return cr_uid_id(method) - elif 'context' in names or kwname: - return cr_uid_context(method) - else: - return cr_uid(method) - elif 'context' in names: - return cr_context(method) - else: - return cr(method) - - # no wrapping by default - return noguess(method) - - -def expected(decorator, func): - """ Decorate ``func`` with ``decorator`` if ``func`` is not wrapped yet. """ - return decorator(func) if not hasattr(func, '_api') else func - - def _call_kw_model(method, self, args, kwargs): context, args, kwargs = split_context(method, args, kwargs) recs = self.with_context(context or {}) diff --git a/odoo/models.py b/odoo/models.py index 0ffac157bc6..e9c09e5625f 100644 --- a/odoo/models.py +++ b/odoo/models.py @@ -298,7 +298,6 @@ class BaseModel(MetaModel('DummyModel', (object,), {'_register': False})): """ pass - @api.model_cr_context def _reflect(self): """ Reflect the model and its fields in the models 'ir.model' and 'ir.model.fields'. Also create entries in 'ir.model.data' if the key @@ -2281,7 +2280,6 @@ class BaseModel(MetaModel('DummyModel', (object,), {'_register': False})): else: return '"%s"."%s"' % (alias, fname) - @api.model_cr def _parent_store_compute(self): """ Compute parent_path field from scratch. """ if not self._parent_store: @@ -2320,7 +2318,6 @@ class BaseModel(MetaModel('DummyModel', (object,), {'_register': False})): self.invalidate_cache(['parent_path']) return True - @api.model_cr def _check_removed_columns(self, log=False): # iterate on the database columns to drop the NOT NULL constraints of # fields which were required but have been removed (or will be added by @@ -2343,7 +2340,6 @@ class BaseModel(MetaModel('DummyModel', (object,), {'_register': False})): if row['attnotnull']: tools.drop_not_null(cr, self._table, row['attname']) - @api.model_cr_context def _init_column(self, column_name): """ Initialize the value of the given column for existing rows. """ # get the default value; ideally, we should use default_get(), but it @@ -2375,7 +2371,6 @@ class BaseModel(MetaModel('DummyModel', (object,), {'_register': False})): self.env.cr.execute('SELECT 1 FROM "%s" LIMIT 1' % self._table) return self.env.cr.rowcount - @api.model_cr_context def _auto_init(self): """ Initialize the database schema of ``self``: - create the corresponding table, @@ -2446,14 +2441,12 @@ class BaseModel(MetaModel('DummyModel', (object,), {'_register': False})): if parent_path_compute: self._parent_store_compute() - @api.model_cr def init(self): """ This method is called after :meth:`~._auto_init`, and may be overridden to create or modify a model's database schema. """ pass - @api.model_cr def _create_parent_columns(self): tools.create_column(self._cr, self._table, 'parent_path', 'VARCHAR') if 'parent_path' not in self._fields: @@ -2461,7 +2454,6 @@ class BaseModel(MetaModel('DummyModel', (object,), {'_register': False})): elif not self._fields['parent_path'].index: _logger.error('parent_path field on model %s must be indexed! Add index=True to the field definition)', self._name) - @api.model_cr def _add_sql_constraints(self): """ @@ -2489,7 +2481,6 @@ class BaseModel(MetaModel('DummyModel', (object,), {'_register': False})): else: process(key, definition) - @api.model_cr def _execute_sql(self): """ Execute the SQL code from the _sql attribute (if any).""" if hasattr(self, "_sql"): @@ -4527,7 +4518,6 @@ Fields: """ return cls._transient - @api.model_cr def _transient_clean_rows_older_than(self, seconds): assert self._transient, "Model %s is not transient, it cannot be vacuumed!" % self._name # Never delete rows used in last 5 minutes @@ -4539,7 +4529,6 @@ Fields: ids = [x[0] for x in self._cr.fetchall()] self.sudo().browse(ids).unlink() - @api.model_cr def _transient_clean_old_rows(self, max_count): # Check how many rows we have in the table self._cr.execute("SELECT count(*) AS row_count FROM " + self._table) @@ -4682,7 +4671,6 @@ Fields: for record in self: record.active = not record.active - @api.model_cr def _register_hook(self): """ stuff to do right after the registry is built """ pass @@ -4714,7 +4702,7 @@ Fields: origin = getattr(cls, name) method.origin = origin # propagate decorators from origin to method, and apply api decorator - wrapped = api.guess(api.propagate(origin, method)) + wrapped = api.propagate(origin, method) wrapped.origin = origin setattr(cls, name, wrapped)