diff options
| author | Xavier Morel <xmo@odoo.com> | 2017-04-12 09:53:33 +0200 |
|---|---|---|
| committer | Xavier Morel <xmo@odoo.com> | 2017-04-12 13:48:42 +0200 |
| commit | 76852a2fad05292b8d592b76b37e4732f9c60a2d (patch) | |
| tree | 89f532e4d594b815b98f0425397b6156888626c3 | |
| parent | 15e17e7b48f89f6e897a28f5031cdd740a887d80 (diff) | |
[#8530] fix uses of ``reduce`` builtin
Demoted to library in Python 3, see if uses can be replaced by more
specific construct, just import functools.reduce otherwise.
Futurize fixers:
* lib2to3.fixes.fix_reduce
| -rw-r--r-- | addons/account/models/account_invoice.py | 2 | ||||
| -rw-r--r-- | addons/product/models/product_template.py | 21 | ||||
| -rw-r--r-- | addons/rating/models/rating.py | 4 | ||||
| -rw-r--r-- | addons/website_rating_project_issue/controllers/main.py | 2 | ||||
| -rw-r--r-- | doc/python3.rst | 15 | ||||
| -rw-r--r-- | odoo/addons/base/ir/ir_qweb/qweb.py | 1 | ||||
| -rw-r--r-- | odoo/addons/base/res/res_config.py | 3 | ||||
| -rw-r--r-- | odoo/modules/graph.py | 2 | ||||
| -rw-r--r-- | odoo/tools/parse_version.py | 10 | ||||
| -rw-r--r-- | odoo/tools/translate.py | 2 |
10 files changed, 43 insertions, 19 deletions
diff --git a/addons/account/models/account_invoice.py b/addons/account/models/account_invoice.py index 87c8677d2a0..29557781875 100644 --- a/addons/account/models/account_invoice.py +++ b/addons/account/models/account_invoice.py @@ -1464,7 +1464,7 @@ class AccountPaymentTerm(models.Model): next_date += relativedelta(day=31, months=0) # Getting last day of next month result.append((fields.Date.to_string(next_date), amt)) amount -= amt - amount = reduce(lambda x, y: x + y[1], result, 0.0) + amount = sum(amt for _, amt in result) dist = round(value - amount, prec) if dist: last_date = result and result[-1][0] or fields.Date.today() diff --git a/addons/product/models/product_template.py b/addons/product/models/product_template.py index 5e2bcba48f6..0082bbf7793 100644 --- a/addons/product/models/product_template.py +++ b/addons/product/models/product_template.py @@ -383,6 +383,7 @@ class ProductTemplate(models.Model): @api.multi def create_variant_ids(self): Product = self.env["product.product"] + AttributeValues = self.env['product.attribute.value'] for tmpl_id in self.with_context(active_test=False): # adding an attribute with only one value should not recreate product # write this attribute on every product to make sure we don't lose them @@ -391,11 +392,21 @@ class ProductTemplate(models.Model): updated_products = tmpl_id.product_variant_ids.filtered(lambda product: value_id.attribute_id not in product.mapped('attribute_value_ids.attribute_id')) updated_products.write({'attribute_value_ids': [(4, value_id.id)]}) - # list of values combination - existing_variants = [set(variant.attribute_value_ids.ids) for variant in tmpl_id.product_variant_ids] - variant_matrix = itertools.product(*(line.value_ids for line in tmpl_id.attribute_line_ids if line.value_ids and line.value_ids[0].attribute_id.create_variant)) - variant_matrix = map(lambda record_list: reduce(lambda x, y: x+y, record_list, self.env['product.attribute.value']), variant_matrix) - to_create_variants = filter(lambda rec_set: set(rec_set.ids) not in existing_variants, variant_matrix) + # iterator of n-uple of product.attribute.value *ids* + variant_matrix = [ + AttributeValues.browse(value_ids) + for value_ids in itertools.product(*(line.value_ids.ids for line in tmpl_id.attribute_line_ids if line.value_ids[:1].attribute_id.create_variant)) + ] + + # get the value (id) sets of existing variants + existing_variants = {frozenset(variant.attribute_value_ids.ids) for variant in tmpl_id.product_variant_ids} + # -> for each value set, create a recordset of values to create a + # variant for if the value set isn't already a variant + to_create_variants = [ + value_ids + for value_ids in variant_matrix + if set(value_ids.ids) not in existing_variants + ] # check product variants_to_activate = self.env['product.product'] diff --git a/addons/rating/models/rating.py b/addons/rating/models/rating.py index 859d04e8603..3bc5491b6ef 100644 --- a/addons/rating/models/rating.py +++ b/addons/rating/models/rating.py @@ -217,8 +217,8 @@ class RatingMixin(models.AbstractModel): rating_number = sum(values.values()) result = { 'repartition': values, - 'avg': sum([float(key * values[key]) for key in values]) / rating_number if rating_number > 0 else 0, - 'total': reduce(lambda x, y: y['rating_count'] + x, data, 0), + 'avg': sum(float(key * values[key]) for key in values) / rating_number if rating_number > 0 else 0, + 'total': sum(it['rating_count'] for it in data), } return result return values diff --git a/addons/website_rating_project_issue/controllers/main.py b/addons/website_rating_project_issue/controllers/main.py index c819b7171c7..63916880880 100644 --- a/addons/website_rating_project_issue/controllers/main.py +++ b/addons/website_rating_project_issue/controllers/main.py @@ -45,7 +45,7 @@ class WebsiteRatingProject(http.Controller): domdate = domain + [('create_date', '<=', yesterday), ('create_date', '>=', todate)] stats[x] = {1: 0, 5: 0, 10: 0} rating_stats = request.env['rating.rating'].read_group(domdate, [], ['rating']) - total = reduce(lambda x, y: y['rating_count'] + x, rating_stats, 0) + total = sum(st['rating_count'] for st in rating_stats) for rate in rating_stats: stats[x][rate['rating']] = float("%.2f" % (rate['rating_count'] * 100.0 / total)) return {'ratings': ratings, 'stats': stats} diff --git a/doc/python3.rst b/doc/python3.rst index 4506fb9d9f1..cb60965eb6c 100644 --- a/doc/python3.rst +++ b/doc/python3.rst @@ -99,6 +99,21 @@ Removed Operators These two operators were long recommended against/deprecated in Python 2, Python 3 removed them from the language. +Removed/renamed builtins +------------------------ + +``reduce`` +########## + +In Python 3, ``reduce`` has been demoted from builtin to ``functools.reduce``. +However this is because many (if not most) uses of ``reduce`` can be replaced +by ``sum``, ``all``, ``any`` or a list comprehension for a more readable and +faster result. + +It is easy enough to just add ``from functools import reduce`` to the file +and compatible with Python 2.6 and later, but consider whether you get better +code by replacing it with some other method altogether. + Removed/renamed methods ----------------------- diff --git a/odoo/addons/base/ir/ir_qweb/qweb.py b/odoo/addons/base/ir/ir_qweb/qweb.py index e4b618a47e4..0c69bd90baa 100644 --- a/odoo/addons/base/ir/ir_qweb/qweb.py +++ b/odoo/addons/base/ir/ir_qweb/qweb.py @@ -10,6 +10,7 @@ import werkzeug from werkzeug.utils import escape as _escape from itertools import chain, izip, tee import __builtin__ +from functools import reduce builtin_defaults = {name: getattr(__builtin__, name) for name in dir(__builtin__)} try: diff --git a/odoo/addons/base/res/res_config.py b/odoo/addons/base/res/res_config.py index 73eb71580f1..59764fca1e8 100644 --- a/odoo/addons/base/res/res_config.py +++ b/odoo/addons/base/res/res_config.py @@ -458,6 +458,7 @@ class ResConfigSettings(models.TransientModel, ResConfigModuleInstallationMixin) } """ IrModule = self.env['ir.module.module'] + Groups = self.env['res.groups'] ref = self.env.ref defaults, groups, modules, others = [], [], [], [] @@ -467,7 +468,7 @@ class ResConfigSettings(models.TransientModel, ResConfigModuleInstallationMixin) elif name.startswith('group_') and field.type in ('boolean', 'selection') and \ hasattr(field, 'implied_group'): field_group_xmlids = getattr(field, 'group', 'base.group_user').split(',') - field_groups = reduce(add, map(ref, field_group_xmlids)) + field_groups = Groups.concat(*map(ref, field_group_xmlids)) groups.append((name, field_groups, ref(field.implied_group))) elif name.startswith('module_') and field.type in ('boolean', 'selection'): module = IrModule.sudo().search([('name', '=', name[7:])], limit=1) diff --git a/odoo/modules/graph.py b/odoo/modules/graph.py index aaf90ae8443..48cc0e8a6e1 100644 --- a/odoo/modules/graph.py +++ b/odoo/modules/graph.py @@ -91,7 +91,7 @@ class Graph(dict): deps = info['depends'] # if all dependencies of 'package' are already in the graph, add 'package' in the graph - if reduce(lambda x, y: x and y in self, deps, True): + if all(dep in self for dep in deps): if not package in current: packages.pop(0) continue diff --git a/odoo/tools/parse_version.py b/odoo/tools/parse_version.py index 90b1b98e57f..997590f9b35 100644 --- a/odoo/tools/parse_version.py +++ b/odoo/tools/parse_version.py @@ -63,12 +63,6 @@ def parse_version(s): return tuple(parts) if __name__ == '__main__': - - def cmp(a, b): - msg = '%s < %s == %s' % (a, b, a < b) - assert a < b, msg - return b - def chk(lst, verbose=False): pvs = [] for v in lst: @@ -76,7 +70,9 @@ if __name__ == '__main__': pvs.append(pv) if verbose: print v, pv - reduce(cmp, pvs) + + for a, b in zip(pvs, pvs[1:]): + assert a < b, '%s < %s == %s' % (a, b, a < b) chk(('0', '4.2', '4.2.3.4', '5.0.0-alpha', '5.0.0-rc1', '5.0.0-rc1.1', '5.0.0_rc2', '5.0.0_rc3', '5.0.0'), False) chk(('5.0.0-0_rc3', '5.0.0-1dev', '5.0.0-1'), False) diff --git a/odoo/tools/translate.py b/odoo/tools/translate.py index b33b356a2f9..850e911d608 100644 --- a/odoo/tools/translate.py +++ b/odoo/tools/translate.py @@ -599,7 +599,7 @@ class PoFile(object): % { 'project': release.description, 'version': release.version, - 'modules': reduce(lambda s, m: s + "#\t* %s\n" % m, modules, ""), + 'modules': ''.join("#\t* %s\n" % m for m in modules), 'now': datetime.utcnow().strftime('%Y-%m-%d %H:%M')+"+0000", } ) |
