Skip to content

Commit e046269

Browse files
committed
[IMP] *: forbid names reserved by RPC
`ids` and `context` are reserved for RPC calls and cannot be used as paramter names for public functions. closes odoo#218355 Related: odoo/enterprise#89953 Signed-off-by: Raphael Collet <[email protected]>
1 parent dddcd89 commit e046269

File tree

7 files changed

+45
-16
lines changed

7 files changed

+45
-16
lines changed

addons/account/models/account_root.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ class AccountRoot(models.Model):
1515
name = fields.Char(compute='_compute_root')
1616
parent_id = fields.Many2one('account.root', compute='_compute_root')
1717

18+
@api.private
1819
def browse(self, ids=()):
1920
if isinstance(ids, str):
2021
ids = (ids,)

addons/mail/models/mail_mail.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -185,15 +185,15 @@ def cancel(self):
185185
return self.write({'state': 'cancel'})
186186

187187
@api.model
188-
def process_email_queue(self, ids=(), batch_size=1000):
188+
def process_email_queue(self, email_ids=(), batch_size=1000):
189189
"""Send immediately queued messages, committing after each
190190
message is sent - this is not transactional and should
191191
not be called during another transaction!
192192
193193
A maximum of 1K MailMail (configurable using 'mail.mail.queue.batch.size'
194194
optional ICP) are fetched in order to keep time under control.
195195
196-
:param list ids: optional list of emails ids to send. If given only
196+
:param list email_ids: optional list of emails ids to send. If given only
197197
scheduled and outgoing emails within this ids list
198198
are sent;
199199
"""
@@ -207,8 +207,8 @@ def process_email_queue(self, ids=(), batch_size=1000):
207207
if 'filters' in self.env.context:
208208
domain.extend(self.env.context['filters'])
209209
batch_size = int(self.env['ir.config_parameter'].sudo().get_param('mail.mail.queue.batch.size', batch_size)) or batch_size
210-
send_ids = self.search(domain, limit=batch_size if not ids else batch_size * 10).ids
211-
if not ids:
210+
send_ids = self.search(domain, limit=batch_size if not email_ids else batch_size * 10).ids
211+
if not email_ids:
212212
ids_done = set()
213213
total = len(send_ids) if len(send_ids) < batch_size else self.search_count(domain)
214214

@@ -220,7 +220,7 @@ def post_send_callback(ids):
220220
# commit progress only when running from a cron job
221221
self.env['ir.cron']._commit_progress(len(processed), remaining=total - len(ids_done))
222222
else:
223-
send_ids = list(set(send_ids) & set(ids))
223+
send_ids = list(set(send_ids) & set(email_ids))
224224
post_send_callback = None
225225

226226
send_ids.sort()

addons/product_expiry/models/stock_move.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,10 @@ class StockMove(models.Model):
1616
string='Use Expiration Date', related='product_id.use_expiration_date')
1717

1818
@api.model
19-
def action_generate_lot_line_vals(self, context, mode, first_lot, count, lot_text):
20-
vals_list = super().action_generate_lot_line_vals(context, mode, first_lot, count, lot_text)
21-
product = self.env['product.product'].browse(context.get('default_product_id'))
22-
picking = self.env['stock.picking'].browse(context.get('default_picking_id'))
19+
def action_generate_lot_line_vals(self, context_data, mode, first_lot, count, lot_text):
20+
vals_list = super().action_generate_lot_line_vals(context_data, mode, first_lot, count, lot_text)
21+
product = self.env['product.product'].browse(context_data.get('default_product_id'))
22+
picking = self.env['stock.picking'].browse(context_data.get('default_picking_id'))
2323
if product.use_expiration_date:
2424
from_date = picking.scheduled_date or fields.Datetime.today()
2525
expiration_date = from_date + datetime.timedelta(days=product.expiration_time)

addons/stock/models/stock_move.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1011,8 +1011,8 @@ def split_lots(self, lots):
10111011
return move_lines_vals
10121012

10131013
@api.model
1014-
def action_generate_lot_line_vals(self, context, mode, first_lot, count, lot_text):
1015-
if not context.get('default_product_id'):
1014+
def action_generate_lot_line_vals(self, context_data, mode, first_lot, count, lot_text):
1015+
if not context_data.get('default_product_id'):
10161016
raise UserError(_("No product found to generate Serials/Lots for."))
10171017
assert mode in ('generate', 'import')
10181018
default_vals = {}
@@ -1032,9 +1032,9 @@ def remove_prefix(text, prefix):
10321032
if text.startswith(prefix):
10331033
return text[len(prefix):]
10341034
return text
1035-
for key in context:
1035+
for key in context_data:
10361036
if key.startswith('default_'):
1037-
default_vals[remove_prefix(key, 'default_')] = context[key]
1037+
default_vals[remove_prefix(key, 'default_')] = context_data[key]
10381038

10391039
if default_vals['tracking'] == 'lot' and mode == 'generate':
10401040
lot_qties = generate_lot_qty(default_vals['quantity'], count)

addons/web_editor/models/ir_qweb_fields.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -282,10 +282,10 @@ def attributes(self, record, field_name, options, values=None):
282282
attrs['data-oe-contact-options'] = json.dumps(options)
283283
return attrs
284284

285-
# helper to call the rendering of contact field
286285
@api.model
287-
def get_record_to_html(self, ids, options=None):
288-
return self.value_to_html(self.env['res.partner'].search([('id', '=', ids[0])]), options=options)
286+
def get_record_to_html(self, contact_ids, options=None):
287+
""" Helper to call the rendering of contact field. """
288+
return self.value_to_html(self.env['res.partner'].search([('id', '=', contact_ids[0])]), options=options)
289289

290290

291291
class IrQwebFieldDate(models.AbstractModel):

odoo/addons/test_lint/tests/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from . import test_l10n
1010
from . import test_manifests
1111
from . import test_markers
12+
from . import test_naming
1213
from . import test_onchange_domains
1314
from . import test_orm_import
1415
from . import test_override_signatures
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import inspect
2+
3+
from odoo.modules.registry import Registry
4+
from odoo.tests.common import get_db_name, tagged
5+
6+
from .lint_case import LintCase
7+
8+
9+
@tagged('-at_install', 'post_install')
10+
class TestNaming(LintCase):
11+
failureException = TypeError
12+
13+
def test_parameter_rpc_compatible(self):
14+
"""Parameters "ids" and "context" are not allowed in public methods.
15+
These conflict with standard parameters used in RPC calls.
16+
"""
17+
INVALID_NAMES = {'ids', 'context'}
18+
registry = Registry(get_db_name())
19+
20+
for model_name, model_cls in registry.items():
21+
for method_name, method in inspect.getmembers(model_cls, inspect.isroutine):
22+
if method_name.startswith('_') or getattr(method, '_api_private', False):
23+
continue
24+
25+
with self.subTest(model=model_name, method=method_name):
26+
signature = inspect.signature(method)
27+
self.assertFalse(INVALID_NAMES.intersection(signature.parameters), "Invalid parameter names found")

0 commit comments

Comments
 (0)