diff options
| author | xmo-odoo <xmo@odoo.com> | 2017-04-27 13:59:33 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2017-04-27 13:59:33 +0200 |
| commit | 2e6a589f417af48e3322955ffff6e94b6d8a24e3 (patch) | |
| tree | aa613ecc1f74a9531a03de89aa2bdc7bb32eed3b /odoo/tools | |
| parent | de4a2216b953abb86094c9bfa5f45b1eaaa79d3d (diff) | |
[FIX] builtins removed from Python 3
* Reverse wrapper courtesy of @rco-odoo's original P3 branch
* thin compat module stripped down from werkzeug (to augment as needed)
issue 8530
Diffstat (limited to 'odoo/tools')
| -rw-r--r-- | odoo/tools/config.py | 2 | ||||
| -rw-r--r-- | odoo/tools/convert.py | 6 | ||||
| -rw-r--r-- | odoo/tools/float_utils.py | 16 | ||||
| -rwxr-xr-x | odoo/tools/graph.py | 2 | ||||
| -rw-r--r-- | odoo/tools/image.py | 4 | ||||
| -rw-r--r-- | odoo/tools/import_email.py | 2 | ||||
| -rw-r--r-- | odoo/tools/misc.py | 46 | ||||
| -rw-r--r-- | odoo/tools/pycompat.py | 31 | ||||
| -rw-r--r-- | odoo/tools/safe_eval.py | 9 | ||||
| -rw-r--r-- | odoo/tools/test_reports.py | 6 | ||||
| -rw-r--r-- | odoo/tools/translate.py | 6 |
11 files changed, 102 insertions, 28 deletions
diff --git a/odoo/tools/config.py b/odoo/tools/config.py index c832c1980cd..4443bc7e6d7 100644 --- a/odoo/tools/config.py +++ b/odoo/tools/config.py @@ -549,7 +549,7 @@ class configmanager(object): if not rc_exists and not os.path.exists(os.path.dirname(self.rcfile)): os.makedirs(os.path.dirname(self.rcfile)) try: - p.write(file(self.rcfile, 'w')) + p.write(open(self.rcfile, 'w')) if not rc_exists: os.chmod(self.rcfile, 0o600) except IOError: diff --git a/odoo/tools/convert.py b/odoo/tools/convert.py index 3410b929bc6..3df1d20b50f 100644 --- a/odoo/tools/convert.py +++ b/odoo/tools/convert.py @@ -890,10 +890,10 @@ def convert_xml_import(cr, module, xmlfile, idref=None, mode='init', noupdate=Fa if idref is None: idref={} - if isinstance(xmlfile, file): - xml_filename = xmlfile.name - else: + if isinstance(xmlfile, basestring): xml_filename = xmlfile + else: + xml_filename = xmlfile.name obj = xml_import(cr, module, idref, mode, report=report, noupdate=noupdate, xml_filename=xml_filename) obj.parse(doc.getroot(), mode=mode) return True diff --git a/odoo/tools/float_utils.py b/odoo/tools/float_utils.py index 959299e2c97..8c71d7a29b2 100644 --- a/odoo/tools/float_utils.py +++ b/odoo/tools/float_utils.py @@ -4,6 +4,9 @@ from __future__ import print_function import math +from odoo.tools import pycompat + + def _float_check_precision(precision_digits=None, precision_rounding=None): assert (precision_digits is not None or precision_rounding is not None) and \ not (precision_digits and precision_rounding),\ @@ -54,7 +57,7 @@ def float_round(value, precision_digits=None, precision_rounding=None, rounding_ epsilon_magnitude = math.log(abs(normalized_value), 2) epsilon = 2**(epsilon_magnitude-53) if rounding_method == 'HALF-UP': - normalized_value += cmp(normalized_value,0) * epsilon + normalized_value += math.copysign(epsilon, normalized_value) rounded_value = round(normalized_value) # round to integer # TIE-BREAKING: UP (for ceiling operations) @@ -66,7 +69,7 @@ def float_round(value, precision_digits=None, precision_rounding=None, rounding_ # restored. elif rounding_method == 'UP': - sign = cmp(normalized_value, 0) + sign = math.copysign(1.0, normalized_value) normalized_value -= sign*epsilon rounded_value = math.ceil(abs(normalized_value))*sign # ceil to integer @@ -214,14 +217,13 @@ if __name__ == "__main__": fractions = [.0, .015, .01499, .675, .67499, .4555, .4555, .45555] expecteds = ['.00', '.02', '.01', '.68', '.67', '.46', '.456', '.4556'] precisions = [2, 2, 2, 2, 2, 2, 3, 4] - for magnitude in range(7): - for i in xrange(len(fractions)): - frac, exp, prec = fractions[i], expecteds[i], precisions[i] + for magnitude in pycompat.range(7): + for frac, exp, prec in zip(fractions, expecteds, precisions): for sign in [-1,1]: - for x in xrange(0,10000,97): + for x in pycompat.range(0, 10000, 97): n = x * 10**magnitude f = sign * (n + frac) - f_exp = ('-' if f != 0 and sign == -1 else '') + str(n) + exp + f_exp = ('-' if f != 0 and sign == -1 else '') + str(n) + exp try_round(f, f_exp, precision_digits=prec) stop = time.time() diff --git a/odoo/tools/graph.py b/odoo/tools/graph.py index 454a1dce98f..82fc0e0978a 100755 --- a/odoo/tools/graph.py +++ b/odoo/tools/graph.py @@ -634,7 +634,7 @@ class graph(object): self.init_order(self.start, self.result[self.start]['x']) for level in self.levels: - self.levels[level].sort(lambda x, y: cmp(self.result[x]['y'], self.result[y]['y'])) + self.levels[level].sort(key=lambda x: self.result[x]['y']) self.order_heuristic() self.process_order() diff --git a/odoo/tools/image.py b/odoo/tools/image.py index 952d6b25c4c..481abd3da02 100644 --- a/odoo/tools/image.py +++ b/odoo/tools/image.py @@ -280,6 +280,6 @@ if __name__=="__main__": assert len(sys.argv)==3, 'Usage to Test: image.py SRC.png DEST.png' - img = file(sys.argv[1],'rb').read().encode('base64') + img = open(sys.argv[1],'rb').read().encode('base64') new = image_resize_image(img, (128,100)) - file(sys.argv[2], 'wb').write(new.decode('base64')) + open(sys.argv[2], 'wb').write(new.decode('base64')) diff --git a/odoo/tools/import_email.py b/odoo/tools/import_email.py index 4178ca14a06..74029c693eb 100644 --- a/odoo/tools/import_email.py +++ b/odoo/tools/import_email.py @@ -125,7 +125,7 @@ class ReceiverEmail2Event(object): os.mkdir(newdir) counter += 1 - fd = file(os.path.join(newdir, filename), 'w') + fd = open(os.path.join(newdir, filename), 'w') fd.write(part.get_payload(decode=1)) fd.close() else: diff --git a/odoo/tools/misc.py b/odoo/tools/misc.py index f080d3067ca..d90031e43eb 100644 --- a/odoo/tools/misc.py +++ b/odoo/tools/misc.py @@ -27,6 +27,7 @@ from cStringIO import StringIO from collections import defaultdict, Iterable, Mapping, MutableSet, OrderedDict from itertools import islice, izip, groupby, repeat from lxml import etree + from which import which from threading import local import traceback @@ -41,6 +42,7 @@ except ImportError: from config import config from cache import * from .parse_version import parse_version +from . import pycompat import odoo # get_encodings, ustr and exception_to_unicode were originally from tools.misc. @@ -279,7 +281,7 @@ def flatten(list): return r def reverse_enumerate(l): - """Like enumerate but in the other sens + """Like enumerate but in the other direction Usage:: >>> a = ['a', 'b', 'c'] @@ -295,7 +297,7 @@ def reverse_enumerate(l): File "<stdin>", line 1, in <module> StopIteration """ - return izip(xrange(len(l)-1, -1, -1), reversed(l)) + return izip(pycompat.range(len(l)-1, -1, -1), reversed(l)) def partition(pred, elems): """ Return a pair equivalent to: @@ -654,8 +656,11 @@ def posix_to_ldml(fmt, locale): def split_every(n, iterable, piece_maker=tuple): """Splits an iterable into length-n pieces. The last piece will be shorter if ``n`` does not evenly divide the iterable length. - @param ``piece_maker``: function to build the pieces - from the slices (tuple,list,...) + + :param int n: maximum size of each generated chunk + :param Iterable iterable: iterable to chunk into pieces + :param piece_maker: callable taking an iterable and collecting each + chunk from its slice, *must consume the entire slice*. """ iterator = iter(iterable) piece = piece_maker(islice(iterator, n)) @@ -990,6 +995,39 @@ class LastOrderedSet(OrderedSet): OrderedSet.discard(self, elem) OrderedSet.add(self, elem) +def unique(it): + """ "Uniquifier" for the provided iterable: will output each element of + the iterable once. + + The iterable's elements must be hashahble. + + :param Iterable it: + :rtype: Iterator + """ + seen = set() + for e in it: + if e not in seen: + seen.add(e) + yield e + +class Reverse(object): + """ Wraps a value and reverses its ordering, useful in key functions when + mixing ascending and descending sort on non-numeric data as the + ``reverse`` parameter can not do piecemeal reordering. + """ + __slots__ = ['val'] + + def __init__(self, val): + self.val = val + + def __eq__(self, other): return self.val == other.val + def __ne__(self, other): return self.val != other.val + + def __ge__(self, other): return self.val <= other.val + def __gt__(self, other): return self.val < other.val + def __le__(self, other): return self.val >= other.val + def __lt__(self, other): return self.val > other.val + @contextmanager def ignore(*exc): try: diff --git a/odoo/tools/pycompat.py b/odoo/tools/pycompat.py new file mode 100644 index 00000000000..114f7f2bd87 --- /dev/null +++ b/odoo/tools/pycompat.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# to remove if we decide to add a dependency on six or future +# very strongly inspired by https://github.com/pallets/werkzeug/blob/master/werkzeug/_compat.py +import sys + +PY2 = sys.version_info[0] + +if PY2: + # pylint: disable=long-builtin,xrange-builtin + integer_types = (int, long) + + range = xrange + + # noinspection PyUnresolvedReferences + from itertools import imap, izip, ifilter + + def implements_iterator(cls): + cls.next = cls.__next__ + del cls.__next__ + return cls +else: + integer_types = (int,) + + range = range + + imap = map + izip = zip + ifilter = filter + + def implements_iterator(cls): + return cls diff --git a/odoo/tools/safe_eval.py b/odoo/tools/safe_eval.py index 14020378c21..ebe97619e35 100644 --- a/odoo/tools/safe_eval.py +++ b/odoo/tools/safe_eval.py @@ -16,11 +16,14 @@ condition/math builtins. # - safe_eval in tryton http://hg.tryton.org/hgwebdir.cgi/trytond/rev/bbb5f73319ad from opcode import HAVE_ARGUMENT, opmap + +import functools from psycopg2 import OperationalError from types import CodeType import logging import werkzeug +from odoo.tools import pycompat from .misc import ustr import odoo @@ -226,7 +229,6 @@ _BUILTINS = { 'bool': bool, 'int': int, 'float': float, - 'long': long, 'enumerate': enumerate, 'dict': dict, 'list': list, @@ -236,7 +238,7 @@ _BUILTINS = { 'min': min, 'max': max, 'sum': sum, - 'reduce': reduce, + 'reduce': functools.reduce, 'filter': filter, 'round': round, 'len': len, @@ -246,11 +248,10 @@ _BUILTINS = { 'any': any, 'ord': ord, 'chr': chr, - 'cmp': cmp, 'divmod': divmod, 'isinstance': isinstance, 'range': range, - 'xrange': xrange, + 'xrange': pycompat.range, 'zip': zip, 'Exception': Exception, } diff --git a/odoo/tools/test_reports.py b/odoo/tools/test_reports.py index ef09862bc01..c1f9af8bb55 100644 --- a/odoo/tools/test_reports.py +++ b/odoo/tools/test_reports.py @@ -11,6 +11,8 @@ import odoo import odoo.report import odoo.tools as tools import logging + +from odoo.tools import pycompat from odoo.tools.safe_eval import safe_eval from subprocess import Popen, PIPE import os @@ -45,7 +47,7 @@ def try_report(cr, uid, rname, ids, data=None, context=None, our_module=None, re raise ValueError("Report %s produced an empty result!" % rname) if tools.config['test_report_directory']: - file(os.path.join(tools.config['test_report_directory'], rname+ '.'+res_format), 'wb+').write(res_data) + open(os.path.join(tools.config['test_report_directory'], rname+ '.'+res_format), 'wb+').write(res_data) _logger.debug("Have a %s report for %s, will examine it", res_format, rname) if res_format == 'pdf': @@ -128,7 +130,7 @@ def try_report_action(cr, uid, action_id, active_model=None, active_ids=None, action = env.ref(action_id) act_model, act_id = action._name, action.id else: - assert isinstance(action_id, (long, int)) + assert isinstance(action_id, pycompat.integer_types) act_model = 'ir.action.act_window' # assume that act_id = action_id act_xmlid = '<%s>' % act_id diff --git a/odoo/tools/translate.py b/odoo/tools/translate.py index 16a7bd9015e..75495b4bbae 100644 --- a/odoo/tools/translate.py +++ b/odoo/tools/translate.py @@ -20,7 +20,7 @@ from babel.messages import extract from lxml import etree import odoo -from odoo.tools import config +from odoo.tools import config, pycompat from odoo.tools.misc import file_open, get_iso_codes, SKIPPED_ELEMENT_TYPES from odoo.tools.osutil import walksymlinks from odoo import sql_db, SUPERUSER_ID @@ -679,7 +679,7 @@ def trans_export(lang, modules, buffer, format, cr): tmpmoddir = join(tmpdir, mod, 'i18n') os.makedirs(tmpmoddir) pofilename = (lang if lang else mod) + ".po" + ('t' if not lang else '') - buf = file(join(tmpmoddir, pofilename), 'w') + buf = open(join(tmpmoddir, pofilename), 'w') _process('po', [mod], modrows, buf, lang) buf.close() @@ -1106,7 +1106,7 @@ def trans_load_data(cr, fileobj, fileformat, lang, lang_name=None, verbose=True, if not res_id: return - if isinstance(res_id, (int, long)) or \ + if isinstance(res_id, pycompat.integer_types) or \ (isinstance(res_id, basestring) and res_id.isdigit()): dic['res_id'] = int(res_id) if module_name: |
