Skip to content

Code inspection ​

Get warnings in Python and XML files when your code departs from Odoo's coding guidelines. The checks run as you open, edit and save a file, and appear in the editor and the Problems panel.

Code standard warnings shown in an Odoo Python file

What you can do ​

The checks follow Odoo's coding guidelines. Every finding is a Warning, shown on the line that triggers it. The checks cover .py and .xml files. They do not cover CSV files such as ir.model.access.csv.

Python: model files ​

These checks run on Python files in a models/ folder.

RuleWarning exampleFlagged code
File name matches the class. SaleOrder goes in sale_order.py.File name should be 'sale_order.py' for class 'SaleOrder'class SaleOrder(models.Model) in saleorder.py
Model classes use CamelCase.Model class 'sale_order' should use CamelCaseclass sale_order(models.Model):
Model _name uses the singular.Model name 'sale.orders' should use singular form_name = 'sale.orders'
Transient model _name follows <base_model>.<action>.Transient model name should follow pattern '<base_model>.<action>'_name = 'saleorderimport' in a TransientModel

Python: all files ​

RuleWarning exampleFlagged code
Do not use .clone(). Use dict(my_dict) or list(old_list).Don't use .clone()new_dict = old_dict.clone()
Do not call cr.commit() yourself.NEVER call cr.commit() yourself unless you created your own cursorself.env.cr.commit()
Do not format a string before translating it.Don't format strings before translation_('Hello %s' % name)
Do not concatenate inside _(). Write the full string.Don't use concatenated strings inside translation functions_('Hello ' + name)
Do not format after translating.Don't format after translation_('Hello') % name
Do not nest _() calls.Don't nest translation calls_('Name: %s' % _(self.name))
Test a collection directly.Use 'if collection:' instead of 'if len(collection) > 0:'if len(records) > 0:
Iterate a dictionary directly.Use 'for key in my_dict:'for key in my_dict.keys():
Do not pass None as the default of .get()..get('key', None) is redundantmy_dict.get('foo', None)
Many2one field names end in _id.Many2One field 'partner' should have '_id' suffixpartner = fields.Many2one('res.partner')
One2many and Many2many field names end in _ids.One2Many field 'lines' should have '_ids' suffixlines = fields.One2many('sale.order.line', 'order_id')
action_ methods call self.ensure_one() near the top.Action methods should call self.ensure_one() at the beginningdef action_confirm(self): without self.ensure_one() in the next few lines
Imports are ordered: standard library, then odoo, then odoo.addons.Wrong import order. Should be: 1) Python stdlib, 2) Odoo core, 3) Odoo addonsimport os below from odoo import api

Python: method names ​

A method whose name contains one of these keywords must start with the matching prefix.

KeywordRequired prefixFlaggedAccepted
compute_compute_<field_name>compute_amount_total_compute_amount_total
search_search_<field_name>search_partner_search_partner
default_default_<field_name>default_currency_default_currency
selection_selection_<field_name>selection_state_selection_state
onchange_onchange_<field_name>onchange_partner_id_onchange_partner_id
check_check_<constraint_name>check_amount_total_check_amount_total
actionaction_<action_name>do_actionaction_confirm

XML ​

RuleWarning exampleFlagged code
id comes before model on <record>.Place 'id' attribute before 'model' in <record><record model="ir.ui.view" id="sale_order_view_form">
name is the first attribute of <field>.The 'name' attribute should be the first in <field><field type="char" name="name">
Put noupdate="1" on <odoo>, not on <data>.Use noupdate="1" on <odoo> tag instead of <data><data noupdate="1">
Use <menuitem>.Use <menuitem> tag instead of <record model="ir.ui.menu"><record id="menu_sale" model="ir.ui.menu">
View record IDs follow <model>_view_<type>, with _inherit for inherited views.View ID 'view_sale_order_form' should follow pattern: <model_name>_view_<view_type><record id="view_sale_order_form" model="ir.ui.view">
View names use dots: <model.name>.view.<type>.View name 'sale_order_view_form' should use dots instead of underscores<field name="name">sale_order_view_form</field>
Inherited view names contain .inherit.<details>.Inherited view name '...' should contain '.inherit.<details>' suffix<field name="name">sale.order.view.form.partner</field>

View types in IDs and names are form, list, kanban, search, calendar, graph, pivot and activity.

IDs that contain a keyword must match a pattern. IDs without the keyword are not checked.

ID containsPatternExample
_menu<model>_menu or <model>_menu_<detail>sale_order_menu, sale_order_menu_main
_action<model>_action or <model>_action_<detail>sale_order_action
_group_<module>_group_<group_name>sale_group_manager
_rule_<model>_rule_<group>sale_order_rule_company

File names ​

The check uses the name of the folder that holds the file.

FolderFileRule
views/XMLEnds with _views.xml, _templates.xml or _menus.xml.
security/XMLEnds with _groups.xml or _security.xml.
report/XMLEnds with _report_views.xml, _reports.xml or _templates.xml.
wizard/XMLEnds with _views.xml.
data/XMLEnds with _data.xml or _demo.xml.
controllers/PythonSnake case: lowercase letters and _.
wizard/PythonSnake case: lowercase letters and _.
report/PythonEnds with _report.py.

Get started ​

The linter is off by default. To turn it on:

  1. Open Settings and search for Enable Code Standard Warnings, or set cybrosys-assista-odoo-helper.enableCodeStandardWarnings to true.
  2. Open a Python or XML file in an Odoo module and edit it. Warnings appear in the editor and in the Problems panel (Ctrl+Shift+M, or Cmd+Shift+M on macOS).

Turn the setting off to clear the warnings.

Tips and limits ​

  • Guidelines change between Odoo releases. Check the current Odoo coding guidelines if a warning looks wrong for your version.
  • The checks are a subset of the guidelines, not a full replacement for review. They match text on one line at a time, so a tag whose attributes span several lines is not checked.
  • The checks are approximate and can flag valid code:
    • The translation rule looks for % inside _(), so it also flags the recommended _('Hello %s', name).
    • The method rule looks for the keyword anywhere in the name. research_topics (contains search) and _compute_default_price (contains default) are flagged.
    • The plural rule flags a model name whose last word ends in s, such as x.status.
    • Elements inside a view's arch that have an id attribute are tested against the view ID pattern.
  • Model tools write view IDs such as sale_order_form_view and report files named report/<model>_pdf_report.xml. Both fail these rules. Rename them if you want a clean Problems panel.
  • You cannot turn off individual rules. The setting enables or disables all of them.

Next steps ​

Built by Cybrosys Technologies.