details: https://code.tryton.org/tryton/commit/c28c787fd5a2
branch: default
user: Cédric Krier <[email protected]>
date: Thu Apr 23 19:04:43 2026 +0200
description:
Use defaultdict as result of get method of Field
This prevents loop to fill the result with default value.
diffstat:
trytond/trytond/model/fields/binary.py | 13 ++++++-------
trytond/trytond/model/fields/dict.py | 7 ++++---
trytond/trytond/model/fields/many2many.py | 13 ++++---------
trytond/trytond/model/fields/multiselection.py | 7 ++++---
trytond/trytond/model/fields/one2many.py | 9 ++++-----
trytond/trytond/model/fields/one2one.py | 9 +++++----
trytond/trytond/model/fields/reference.py | 24 +++++++++++++-----------
7 files changed, 40 insertions(+), 42 deletions(-)
diffs (266 lines):
diff -r fb4749715cb6 -r c28c787fd5a2 trytond/trytond/model/fields/binary.py
--- a/trytond/trytond/model/fields/binary.py Thu Apr 23 00:56:02 2026 +0200
+++ b/trytond/trytond/model/fields/binary.py Thu Apr 23 19:04:43 2026 +0200
@@ -2,6 +2,7 @@
# this repository contains the full copyright notices and license terms.
import logging
+from collections import defaultdict
from sql import Column, Literal, Null
from sql.functions import CurrentTimestamp
@@ -63,7 +64,6 @@
if values is None:
values = {}
transaction = Transaction()
- res = {}
converter = self.cast
default = None
format_ = Transaction().context.get(
@@ -71,6 +71,7 @@
if format_ == 'size':
converter = len
default = 0
+ result = defaultdict(type(default))
if self.file_id:
table = model.__table__()
@@ -93,24 +94,22 @@
& (Column(table, self.file_id) != '')))
for record_id, file_id in cursor:
try:
- res[record_id] = store_func(file_id, prefix)
+ result[record_id] = store_func(file_id, prefix)
except (IOError, OSError):
logger.exception(
"failed to retrieve %r from filestore at %r",
file_id, prefix)
for i in values:
- if i['id'] in res:
+ if i['id'] in result:
continue
value = i[name]
if value:
value = converter(value)
else:
value = default
- res[i['id']] = value
- for i in ids:
- res.setdefault(i, default)
- return res
+ result[i['id']] = value
+ return result
def queue_for_removal(self, Model, name, ids):
pool = Pool()
diff -r fb4749715cb6 -r c28c787fd5a2 trytond/trytond/model/fields/dict.py
--- a/trytond/trytond/model/fields/dict.py Thu Apr 23 00:56:02 2026 +0200
+++ b/trytond/trytond/model/fields/dict.py Thu Apr 23 19:04:43 2026 +0200
@@ -1,6 +1,7 @@
# This file is part of Tryton. The COPYRIGHT file at the toplevel of this
# repository contains the full copyright notices and license terms.
import json
+from collections import defaultdict
from functools import partial
from sql import Cast, CombiningQuery, Literal, Null, Select, operators
@@ -34,7 +35,7 @@
self.search_unaccented = True
def get(self, ids, model, name, values=None):
- dicts = dict((id, None) for id in ids)
+ result = defaultdict(type(None))
for value in values or []:
data = value[name]
if data:
@@ -44,8 +45,8 @@
for key, val in data.items():
if isinstance(val, list):
data[key] = tuple(val)
- dicts[value['id']] = ImmutableDict(data)
- return dicts
+ result[value['id']] = ImmutableDict(data)
+ return result
def sql_format(self, value):
value = super().sql_format(value)
diff -r fb4749715cb6 -r c28c787fd5a2 trytond/trytond/model/fields/many2many.py
--- a/trytond/trytond/model/fields/many2many.py Thu Apr 23 00:56:02 2026 +0200
+++ b/trytond/trytond/model/fields/many2many.py Thu Apr 23 19:04:43 2026 +0200
@@ -128,13 +128,7 @@
'''
Return target records ordered.
'''
- if values is None:
- values = {}
- res = {}
- if not ids:
- return res
- for i in ids:
- res[i] = []
+ result = defaultdict(list)
Relation = self.get_relation()
origin_field = Relation._fields[self.origin]
@@ -171,8 +165,9 @@
origin_id = int(origin_id)
else:
origin_id = relation[self.origin]
- res[origin_id].append(relation[self.target])
- return dict((key, tuple(value)) for key, value in res.items())
+ result[origin_id].append(relation[self.target])
+ return defaultdict(
+ tuple, ((key, tuple(value)) for key, value in result.items()))
def set(self, Model, name, ids, values, *args):
'''
diff -r fb4749715cb6 -r c28c787fd5a2
trytond/trytond/model/fields/multiselection.py
--- a/trytond/trytond/model/fields/multiselection.py Thu Apr 23 00:56:02
2026 +0200
+++ b/trytond/trytond/model/fields/multiselection.py Thu Apr 23 19:04:43
2026 +0200
@@ -1,6 +1,7 @@
# This file is part of Tryton. The COPYRIGHT file at the toplevel of this
# repository contains the full copyright notices and license terms.
import json
+from collections import defaultdict
from functools import partial
from sql import Literal, operators
@@ -57,15 +58,15 @@
self.selection, RPC(instantiate=instantiate, cache=cache))
def get(self, ids, model, name, values=None):
- lists = {id: () for id in ids}
+ result = defaultdict(tuple)
for value in values or []:
data = value[name]
if data:
# If stored as JSON conversion is done on backend
if isinstance(data, str):
data = json.loads(data)
- lists[value['id']] = tuple(data)
- return lists
+ result[value['id']] = tuple(data)
+ return result
def sql_format(self, value):
value = super().sql_format(value)
diff -r fb4749715cb6 -r c28c787fd5a2 trytond/trytond/model/fields/one2many.py
--- a/trytond/trytond/model/fields/one2many.py Thu Apr 23 00:56:02 2026 +0200
+++ b/trytond/trytond/model/fields/one2many.py Thu Apr 23 19:04:43 2026 +0200
@@ -140,9 +140,7 @@
Target = self.get_target()
field = Target._fields[self.field]
reference_key = field._type == 'reference'
- res = {}
- for i in ids:
- res[i] = []
+ result = defaultdict(list)
if field.sortable(Target):
if reference_key:
@@ -175,8 +173,9 @@
origin_id = int(origin_id)
else:
origin_id = target[self.field]
- res[origin_id].append(target['id'])
- return dict((key, tuple(value)) for key, value in res.items())
+ result[origin_id].append(target['id'])
+ return defaultdict(
+ tuple, ((key, tuple(value)) for key, value in result.items()))
def set(self, Model, name, ids, values, *args):
'''
diff -r fb4749715cb6 -r c28c787fd5a2 trytond/trytond/model/fields/one2one.py
--- a/trytond/trytond/model/fields/one2one.py Thu Apr 23 00:56:02 2026 +0200
+++ b/trytond/trytond/model/fields/one2one.py Thu Apr 23 19:04:43 2026 +0200
@@ -1,6 +1,8 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
+from collections import defaultdict
+
from trytond.model.fields.field import Field, instantiate_context
from trytond.model.fields.many2many import Many2Many
from trytond.pool import Pool
@@ -21,10 +23,9 @@
:param values: a dictionary with the read values
:return: a dictionary with ids as key and target id as value
'''
- res = super().get(ids, model, name, values=values)
- for i, vals in res.items():
- res[i] = vals[0] if vals else None
- return res
+ result = super().get(ids, model, name, values=values)
+ return defaultdict(
+ type(None), ((k, v[0] if v else None) for k, v in result.items()))
def set(self, Model, name, ids, value, *args):
'''
diff -r fb4749715cb6 -r c28c787fd5a2 trytond/trytond/model/fields/reference.py
--- a/trytond/trytond/model/fields/reference.py Thu Apr 23 00:56:02 2026 +0200
+++ b/trytond/trytond/model/fields/reference.py Thu Apr 23 19:04:43 2026 +0200
@@ -1,6 +1,7 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
import warnings
+from collections import defaultdict
from sql import Cast, Expression, Literal, Null, Query
from sql.functions import Position, Substring
@@ -123,17 +124,17 @@
pool = Pool()
if values is None:
values = {}
- res = {}
+ result = defaultdict(type(None))
for i in values:
- res[i['id']] = i[name]
+ result[i['id']] = i[name]
ref_to_check = {}
for i in ids:
- if not (i in res):
- res[i] = None
+ if not (i in result):
+ result[i] = None
continue
- if not res[i]:
+ if not result[i]:
continue
- ref_model, ref_id = res[i].split(',', 1)
+ ref_model, ref_id = result[i].split(',', 1)
if not ref_model:
continue
try:
@@ -142,7 +143,7 @@
continue
if ref_id < 0:
continue
- res[i] = ref_model + ',' + str(ref_id)
+ result[i] = ref_model + ',' + str(ref_id)
ref_to_check.setdefault(ref_model, (set(), []))
ref_to_check[ref_model][0].add(ref_id)
ref_to_check[ref_model][1].append(i)
@@ -153,7 +154,8 @@
try:
pool.get(ref_model)
except KeyError:
- res.update(dict((i, None) for i in ids))
+ for i in ids:
+ result.pop(i, None)
continue
Ref = pool.get(ref_model)
refs = Ref.search([
@@ -161,9 +163,9 @@
], order=[])
refs = list(map(str, refs))
for i in ids:
- if res[i] not in refs:
- res[i] = None
- return res
+ if result[i] not in refs:
+ result.pop(i, None)
+ return result
def __set__(self, inst, value):
from ..model import Model