summaryrefslogtreecommitdiff
path: root/odoo/tools
diff options
context:
space:
mode:
authorxmo-odoo <xmo@odoo.com>2017-04-27 13:59:33 +0200
committerGitHub <noreply@github.com>2017-04-27 13:59:33 +0200
commit2e6a589f417af48e3322955ffff6e94b6d8a24e3 (patch)
treeaa613ecc1f74a9531a03de89aa2bdc7bb32eed3b /odoo/tools
parentde4a2216b953abb86094c9bfa5f45b1eaaa79d3d (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.py2
-rw-r--r--odoo/tools/convert.py6
-rw-r--r--odoo/tools/float_utils.py16
-rwxr-xr-xodoo/tools/graph.py2
-rw-r--r--odoo/tools/image.py4
-rw-r--r--odoo/tools/import_email.py2
-rw-r--r--odoo/tools/misc.py46
-rw-r--r--odoo/tools/pycompat.py31
-rw-r--r--odoo/tools/safe_eval.py9
-rw-r--r--odoo/tools/test_reports.py6
-rw-r--r--odoo/tools/translate.py6
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: