OD125 python-api-deprecated¶
The module uses a Python API its series deprecates or ignores.
| Category | Severity | Series | Needs the index |
|---|---|---|---|
| Deprecation | Warning | saas~12.5 and later | no |
What it reports¶
A form of the Python API that Odoo warns about in the module's series and still runs, from the series in the second column until the one in the third, where Odoo ignores the form, as the next table lists, or removes it, which OD126 reports:
| Form | Deprecated from | Ignored or removed from | Use instead |
|---|---|---|---|
field option track_visibility= |
saas~13.4 | saas~18.1, ignored | tracking= |
sudo(user) |
saas~12.5 | saas~15.3 | with_user(user) |
an @api.onchange method returning domain |
saas~13.2 | saas~16.3, ignored | a domain on the field or in the view |
flush(), recompute() on a recordset |
saas~15.4 | saas~16.2 | flush_model(), flush_recordset() or self.env.flush_all() |
invalidate_cache() on a recordset |
saas~15.4 | saas~16.2 | invalidate_model(), invalidate_recordset() or self.env.invalidate_all() |
refresh() on a recordset |
saas~15.2 | saas~16.2 | self.env.invalidate_all(), invalidate_cache() before saas~15.4 |
check_access_rights(), check_access_rule() |
18.0 | saas~19.1 | check_access(), or has_access() for check_access_rights() given raise_exception=False |
read_group() |
saas~18.2 | saas~19.1, before 20.0 | _read_group() |
an override of read_group() in a model class |
saas~18.2 | saas~19.1 | an override of _read_group() or formatted_read_group() |
an import of odoo.osv |
19.0 | saas~19.1 | odoo.fields.Domain |
@route(type='json') |
saas~18.1 | none | type='jsonrpc' |
It reports a form that Odoo accepts and does nothing with from the series in the second column:
| Form | Ignored from | Use instead |
|---|---|---|
field option oldname= |
saas~12.5 | an upgrade script that renames the column |
the context key force_company, in with_context() |
saas~13.1 | with_company(company) |
field option track_visibility= |
saas~18.1 | tracking= |
an @api.onchange method returning domain |
saas~16.3 | a domain on the field or in the view |
an override of _name_search() in a model class |
18.0 | an override of _search_display_name() |
sudo() counts as given a user when its argument is an integer, a ref() or browse() call
with or without .id, or a name whose last word is user or uid, before any id, or
superuser with the id, such as user, self.env.uid, admin_user.id or SUPERUSER_ID. A
name whose first word is is, has or can is a flag, so sudo(is_user) is not given a user,
and by their last word none of self.env.su, as_superuser or self.user_can_edit is.
check_access_rights() passed False as raise_exception= or as its second argument only
answers whether the user may, so the advice for it is has_access().
flush(), recompute(), invalidate_cache() and refresh() are reported on self in a model
class and on a model the code names, such as self.env["res.partner"], since cursors, files and
browsers have methods of these names. A call of any method in the table is not reported when the
enclosing model class defines the method without calling the one it overrides through super(),
and the call reaches that definition: on self, through sudo(), with_context() and the other
methods that keep the model, or on the class's own model, such as self.env["res.users"] in a
class of res.users. A reported override of read_group() covers the name of its
super().read_group() calls, which is not reported again, while a keyword such a call passes
still is. An import is reported once per statement, wherever it sits, so an import inside a
function counts too. An onchange counts when it returns a literal dict with a domain key.
force_company counts as a keyword of with_context() or a key of the literal dict it is given,
so code that only reads the key from the context is not reported.
Why it matters¶
Each deprecated form still works in the series that deprecates it, and logs a DeprecationWarning
or a warning in the server log. A later series removes it, and OD126 reports the same form as an
error from then on, or keeps accepting it and ignores it. type='json' is an alias of jsonrpc,
and the table gives no removal series for it.
Nothing fails on an ignored form, so the module loads and runs and quietly loses the behaviour.
From saas~12.5 Odoo no longer renames the column of a field declared with oldname, so the values
stay in the old column and the field starts empty, and from saas~18.1 a field with
track_visibility and no tracking is no longer tracked in the chatter. saas~13.1 only logs
force_company, so the records keep the current company, saas~16.3 drops the domain of an
onchange, and 18.0 no longer calls an override of _name_search().
The 20.0 read_group() is another method with the name of the old one, so a call of it on 20.0 is
not reported here. OD126 reports one that passes fields=, orderby= or lazy=, and
an override of it, which 20.0 forbids.
Example¶
class SaleOrder(models.Model):
_inherit = "sale.order"
def _confirm_as(self, user):
self.check_access_rights("write")
return self.with_user(user).action_confirm()
On 18.0, check_access_rights() warns on every call, and saas~19.1 no longer has it.
class SaleOrder(models.Model):
_inherit = "sale.order"
def _confirm_as(self, user):
self.check_access("write")
return self.with_user(user).action_confirm()
Fixing¶
oscn check --fix rewrites sudo(user) given only the user to with_user(user), and
track_visibility= given a non-empty string to tracking=True when the call passes neither
tracking= nor track_sequence= and unpacks no dict with **. The other forms are left to rewrite
by hand.
See fixing findings.