Skip to content

Commit

Permalink
[FIX] builtins removed from Python 3
Browse files Browse the repository at this point in the history
* Reverse wrapper courtesy of @rco-odoo's original P3 branch
* thin compat module stripped down from werkzeug (to augment as needed)

issue 8530
  • Loading branch information
xmo-odoo authored Apr 27, 2017
1 parent de4a221 commit 2e6a589
Show file tree
Hide file tree
Showing 73 changed files with 464 additions and 199 deletions.
6 changes: 3 additions & 3 deletions addons/account/models/account.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

from odoo.osv import expression
from odoo.tools.float_utils import float_round as round
from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT
from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT, pycompat
from odoo.exceptions import UserError, ValidationError
from odoo import api, fields, models, _

Expand Down Expand Up @@ -383,7 +383,7 @@ def _prepare_liquidity_account(self, name, company, currency_id, type):
account_code_prefix = company.bank_account_code_prefix or ''
else:
account_code_prefix = company.cash_account_code_prefix or company.bank_account_code_prefix or ''
for num in xrange(1, 100):
for num in pycompat.range(1, 100):
new_code = str(account_code_prefix.ljust(code_digits - 1, '0')) + str(num)
rec = self.env['account.account'].search([('code', '=', new_code), ('company_id', '=', company.id)], limit=1)
if not rec:
Expand Down Expand Up @@ -412,7 +412,7 @@ def create(self, vals):
if not vals.get('code'):
journal_code_base = (vals['type'] == 'cash' and 'CSH' or 'BNK')
journals = self.env['account.journal'].search([('code', 'like', journal_code_base + '%'), ('company_id', '=', company_id)])
for num in xrange(1, 100):
for num in pycompat.range(1, 100):
# journal_code has a maximal size of 5, hence we can enforce the boundary num < 100
journal_code = journal_code_base + str(num)
if journal_code not in journals.mapped('code'):
Expand Down
6 changes: 3 additions & 3 deletions addons/account/models/account_bank_statement.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from odoo import api, fields, models, _
from odoo.osv import expression
from odoo.tools import float_is_zero
from odoo.tools import float_is_zero, pycompat
from odoo.tools import float_compare, float_round
from odoo.tools.misc import formatLang
from odoo.exceptions import UserError, ValidationError
Expand Down Expand Up @@ -874,10 +874,10 @@ def process_reconciliation(self, counterpart_aml_dicts=None, payment_aml_rec=Non
for aml_dict in counterpart_aml_dicts:
if aml_dict['move_line'].reconciled:
raise UserError(_('A selected move line was already reconciled.'))
if isinstance(aml_dict['move_line'], (int, long)):
if isinstance(aml_dict['move_line'], pycompat.integer_types):
aml_dict['move_line'] = aml_obj.browse(aml_dict['move_line'])
for aml_dict in (counterpart_aml_dicts + new_aml_dicts):
if aml_dict.get('tax_ids') and aml_dict['tax_ids'] and isinstance(aml_dict['tax_ids'][0], (int, long)):
if aml_dict.get('tax_ids') and isinstance(aml_dict['tax_ids'][0], pycompat.integer_types):
# Transform the value in the format required for One2many and Many2many fields
aml_dict['tax_ids'] = map(lambda id: (4, id, None), aml_dict['tax_ids'])

Expand Down
3 changes: 2 additions & 1 deletion addons/auth_signup/models/res_partner.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from urlparse import urljoin

from odoo import api, fields, models, _
from odoo.tools import pycompat


class SignupError(Exception):
Expand All @@ -16,7 +17,7 @@ class SignupError(Exception):
def random_token():
# the token has an entropy of about 120 bits (6 bits/char * 20 chars)
chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
return ''.join(random.SystemRandom().choice(chars) for i in xrange(20))
return ''.join(random.SystemRandom().choice(chars) for _ in pycompat.range(20))

def now(**kwargs):
dt = datetime.now() + timedelta(**kwargs)
Expand Down
45 changes: 24 additions & 21 deletions addons/calendar/models/calendar.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from odoo import api, fields, models
from odoo import tools
from odoo.tools.translate import _
from odoo.tools import DEFAULT_SERVER_DATE_FORMAT, DEFAULT_SERVER_DATETIME_FORMAT
from odoo.tools import DEFAULT_SERVER_DATE_FORMAT, DEFAULT_SERVER_DATETIME_FORMAT, pycompat
from odoo.exceptions import UserError, ValidationError


Expand Down Expand Up @@ -47,7 +47,7 @@ def calendar_id2real_id(calendar_id=None, with_date=False):


def get_real_ids(ids):
if isinstance(ids, (basestring, int, long)):
if isinstance(ids, (basestring, pycompat.integer_types)):
return calendar_id2real_id(ids)

if isinstance(ids, (list, tuple)):
Expand All @@ -62,6 +62,15 @@ def is_calendar_id(record_id):
return len(str(record_id).split('-')) != 1


SORT_ALIASES = {
'start': 'sort_start',
'start_date': 'sort_start',
'start_datetime': 'sort_start',
}
def sort_remap(f):
return SORT_ALIASES.get(f, f)


class Contacts(models.Model):
_name = 'calendar.contacts'

Expand Down Expand Up @@ -1062,23 +1071,17 @@ def get_recurrent_ids(self, domain, order=None):
continue
result_data.append(meeting.get_search_fields(order_fields, r_date=r_start_date))

if order_fields:
uniq = lambda it: collections.OrderedDict((id(x), x) for x in it).values()

def comparer(left, right):
for fn, mult in comparers:
result = cmp(fn(left), fn(right))
if result:
return mult * result
return 0

sort_params = [key.split()[0] if key[-4:].lower() != 'desc' else '-%s' % key.split()[0] for key in (order or self._order).split(',')]
sort_params = uniq([comp if comp not in ['start', 'start_date', 'start_datetime'] else 'sort_start' for comp in sort_params])
sort_params = uniq([comp if comp not in ['-start', '-start_date', '-start_datetime'] else '-sort_start' for comp in sort_params])
comparers = [((itemgetter(col[1:]), -1) if col[0] == '-' else (itemgetter(col), 1)) for col in sort_params]
ids = [r['id'] for r in sorted(result_data, cmp=comparer)]

return ids
# seq of (field, should_reverse)
sort_spec = list(tools.unique(
(sort_remap(key.split()[0]), key.lower().endswith(' desc'))
for key in (order or self._order).split(',')
))
def key(record):
return [
tools.Reverse(record[name]) if desc else record[name]
for name, desc in sort_spec
]
return [r['id'] for r in sorted(result_data, key=key)]

@api.multi
def _rrule_serialize(self):
Expand Down Expand Up @@ -1154,7 +1157,7 @@ def _rrule_parse(self, rule_str, data, date_start):
data['final_date'] = rule._until and rule._until.strftime(DEFAULT_SERVER_DATETIME_FORMAT)
#repeat weekly
if rule._byweekday:
for i in xrange(0, 7):
for i in pycompat.range(0, 7):
if i in rule._byweekday:
data[day_list[i]] = True
data['rrule_type'] = 'weekly'
Expand Down Expand Up @@ -1466,7 +1469,7 @@ def read(self, fields=None, load='_classic_read'):
for calendar_id, real_id in select:
res = real_data[real_id].copy()
ls = calendar_id2real_id(calendar_id, with_date=res and res.get('duration', 0) > 0 and res.get('duration') or 1)
if not isinstance(ls, (basestring, int, long)) and len(ls) >= 2:
if not isinstance(ls, (basestring, pycompat.integer_types)) and len(ls) >= 2:
res['start'] = ls[1]
res['stop'] = ls[2]

Expand Down
47 changes: 47 additions & 0 deletions addons/calendar/tests/test_calendar.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,3 +97,50 @@ def test_calender_event(self):
self.assertEqual(calendar_event_sprint_review.month_by, 'day', 'rrule_type should be mothly')
self.assertEqual(calendar_event_sprint_review.byday, '1', 'rrule_type should be mothly')
self.assertEqual(calendar_event_sprint_review.week_list, 'MO', 'rrule_type should be mothly')

def test_event_order(self):
""" check the ordering of events when searching """
def create_event(name, date):
return self.CalendarEvent.create({
'name': name,
'start': date + ' 12:00:00',
'stop': date + ' 14:00:00',
'duration': 2.0,
})
foo1 = create_event('foo', '2011-04-01')
foo2 = create_event('foo', '2011-06-01')
bar1 = create_event('bar', '2011-05-01')
bar2 = create_event('bar', '2011-06-01')
domain = [('id', 'in', (foo1 + foo2 + bar1 + bar2).ids)]

# sort them by name only
events = self.CalendarEvent.search(domain, order='name')
self.assertEqual(events.mapped('name'), ['bar', 'bar', 'foo', 'foo'])
events = self.CalendarEvent.search(domain, order='name desc')
self.assertEqual(events.mapped('name'), ['foo', 'foo', 'bar', 'bar'])

# sort them by start date only
events = self.CalendarEvent.search(domain, order='start')
self.assertEqual(events.mapped('start'), (foo1 + bar1 + foo2 + bar2).mapped('start'))
events = self.CalendarEvent.search(domain, order='start desc')
self.assertEqual(events.mapped('start'), (foo2 + bar2 + bar1 + foo1).mapped('start'))

# sort them by name then start date
events = self.CalendarEvent.search(domain, order='name asc, start asc')
self.assertEqual(list(events), [bar1, bar2, foo1, foo2])
events = self.CalendarEvent.search(domain, order='name asc, start desc')
self.assertEqual(list(events), [bar2, bar1, foo2, foo1])
events = self.CalendarEvent.search(domain, order='name desc, start asc')
self.assertEqual(list(events), [foo1, foo2, bar1, bar2])
events = self.CalendarEvent.search(domain, order='name desc, start desc')
self.assertEqual(list(events), [foo2, foo1, bar2, bar1])

# sort them by start date then name
events = self.CalendarEvent.search(domain, order='start asc, name asc')
self.assertEqual(list(events), [foo1, bar1, bar2, foo2])
events = self.CalendarEvent.search(domain, order='start asc, name desc')
self.assertEqual(list(events), [foo1, bar1, foo2, bar2])
events = self.CalendarEvent.search(domain, order='start desc, name asc')
self.assertEqual(list(events), [bar2, foo2, bar1, foo1])
events = self.CalendarEvent.search(domain, order='start desc, name desc')
self.assertEqual(list(events), [foo2, bar2, bar1, foo1])
5 changes: 3 additions & 2 deletions addons/gamification/models/goal.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

from odoo import api, fields, models, _, exceptions
from odoo.osv import expression
from odoo.tools import pycompat
from odoo.tools.safe_eval import safe_eval

_logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -281,7 +282,7 @@ def update_goal(self):
safe_eval(code, cxt, mode="exec", nocopy=True)
# the result of the evaluated codeis put in the 'result' local variable, propagated to the context
result = cxt.get('result')
if result is not None and isinstance(result, (float, int, long)):
if result is not None and isinstance(result, (float, pycompat.integer_types)):
goals_to_write.update(goal._get_write_values(result))
else:
_logger.error(
Expand Down Expand Up @@ -322,7 +323,7 @@ def update_goal(self):
for goal in [g for g in goals if g.id in query_goals]:
for user_value in user_values:
queried_value = field_name in user_value and user_value[field_name] or False
if isinstance(queried_value, tuple) and len(queried_value) == 2 and isinstance(queried_value[0], (int, long)):
if isinstance(queried_value, tuple) and len(queried_value) == 2 and isinstance(queried_value[0], pycompat.integer_types):
queried_value = queried_value[0]
if queried_value == query_goals[goal.id]:
new_value = user_value.get(field_name+'_count', goal.current)
Expand Down
4 changes: 2 additions & 2 deletions addons/hr_payroll/tests/test_payslip_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,12 +74,12 @@ def test_00_payslip_flow(self):
# I print the payslip report
data, format = render_report(self.env.cr, self.env.uid, richard_payslip.ids, 'hr_payroll.report_payslip', {}, {})
if config.get('test_report_directory'):
file(os.path.join(config['test_report_directory'], 'hr_payroll-payslip.'+ format), 'wb+').write(data)
open(os.path.join(config['test_report_directory'], 'hr_payroll-payslip.'+ format), 'wb+').write(data)

# I print the payslip details report
data, format = render_report(self.env.cr, self.env.uid, richard_payslip.ids, 'hr_payroll.report_payslipdetails', {}, {})
if config.get('test_report_directory'):
file(os.path.join(config['test_report_directory'], 'hr_payroll-payslipdetails.'+ format), 'wb+').write(data)
open(os.path.join(config['test_report_directory'], 'hr_payroll-payslipdetails.'+ format), 'wb+').write(data)

# I print the contribution register report
context = {'model': 'hr.contribution.register', 'active_ids': [self.ref('hr_payroll.hr_houserent_register')]}
Expand Down
3 changes: 1 addition & 2 deletions addons/hw_escpos/escpos/escpos.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,8 +168,7 @@ def pop(self):
def to_escpos(self):
""" converts the current style to an escpos command string """
cmd = ''
ordered_cmds = self.cmds.keys()
ordered_cmds.sort(lambda x,y: cmp(self.cmds[x]['_order'], self.cmds[y]['_order']))
ordered_cmds = sorted(self.cmds.keys(), key=lambda x: self.cmds[x]['_order'])
for style in ordered_cmds:
cmd += self.cmds[style][self.get(style)]
return cmd
Expand Down
3 changes: 2 additions & 1 deletion addons/l10n_ch/models/mail_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import base64

from odoo import api, models
from odoo.tools import pycompat


class MailTemplate(models.Model):
Expand All @@ -20,7 +21,7 @@ def generate_email(self, res_ids, fields=None):
rslt = super(MailTemplate, self).generate_email(res_ids, fields)

multi_mode = True
if isinstance(res_ids, (int, long)):
if isinstance(res_ids, pycompat.integer_types):
res_ids = [res_ids]
multi_mode = False

Expand Down
2 changes: 1 addition & 1 deletion addons/l10n_in_hr_payroll/tests/test_payment_advice.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,4 @@ def test_00_payment_advice_flow(self):
# In order to test the PDF report defined on a Payment Advice, we will print a Print Advice Report when NEFT is checked
data, format = render_report(self.env.cr, self.env.uid, payment_advice.ids, 'l10n_in_hr_payroll.report_payrolladvice', {}, {})
if config.get('test_report_directory'):
file(os.path.join(config['test_report_directory'], 'l10n_in_hr_payroll_summary_report' + format), 'wb+').write(data)
open(os.path.join(config['test_report_directory'], 'l10n_in_hr_payroll_summary_report' + format), 'wb+').write(data)
12 changes: 7 additions & 5 deletions addons/mail/models/mail_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
import datetime
import dateutil.relativedelta as relativedelta
import logging

import functools
import lxml
import urlparse

Expand All @@ -15,6 +17,7 @@
from odoo import _, api, fields, models, tools
from odoo import report as odoo_report
from odoo.exceptions import UserError
from odoo.tools import pycompat

_logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -90,10 +93,9 @@ def format_tz(env, dt, tz=False, format=False):
'max': max,
'sum': sum,
'filter': filter,
'reduce': reduce,
'reduce': functools.reduce,
'map': map,
'round': round,
'cmp': cmp,

# dateutil.relativedelta is an old-style class and cannot be directly
# instanciated wihtin a jinja2 expression, so a lambda "proxy" is
Expand Down Expand Up @@ -340,7 +342,7 @@ def render_template(self, template_txt, model, res_ids, post_process=False):
:param int res_ids: list of ids of document records those mails are related to.
"""
multi_mode = True
if isinstance(res_ids, (int, long)):
if isinstance(res_ids, pycompat.integer_types):
multi_mode = False
res_ids = [res_ids]

Expand Down Expand Up @@ -385,7 +387,7 @@ def render_template(self, template_txt, model, res_ids, post_process=False):
@api.multi
def get_email_template(self, res_ids):
multi_mode = True
if isinstance(res_ids, (int, long)):
if isinstance(res_ids, pycompat.integer_types):
res_ids = [res_ids]
multi_mode = False

Expand Down Expand Up @@ -450,7 +452,7 @@ def generate_email(self, res_ids, fields=None):
"""
self.ensure_one()
multi_mode = True
if isinstance(res_ids, (int, long)):
if isinstance(res_ids, pycompat.integer_types):
res_ids = [res_ids]
multi_mode = False
if fields is None:
Expand Down
3 changes: 2 additions & 1 deletion addons/mail/models/mail_thread.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
from werkzeug import url_encode

from odoo import _, api, exceptions, fields, models, tools
from odoo.tools import pycompat
from odoo.tools.safe_eval import safe_eval


Expand Down Expand Up @@ -1811,7 +1812,7 @@ def message_post(self, body='', subject=None, message_type='notification',
partner_ids.add(partner_id[1])
if isinstance(partner_id, (list, tuple)) and partner_id[0] == 6 and len(partner_id) == 3:
partner_ids |= set(partner_id[2])
elif isinstance(partner_id, (int, long)):
elif isinstance(partner_id, pycompat.integer_types):
partner_ids.add(partner_id)
else:
pass # we do not manage anything else
Expand Down
11 changes: 6 additions & 5 deletions addons/mail/models/res_partner.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import logging
import threading

from odoo.tools.misc import split_every

from odoo import _, api, fields, models, registry, SUPERUSER_ID
from odoo.osv import expression

Expand Down Expand Up @@ -107,19 +109,18 @@ def _notify_prepare_email_values(self, message):
@api.model
def _notify_send(self, body, subject, recipients, **mail_values):
emails = self.env['mail.mail']
recipients_nbr, recipients_max = len(recipients), 50
email_chunks = [recipients[x:x + recipients_max] for x in xrange(0, len(recipients), recipients_max)]
for email_chunk in email_chunks:
recipients_nbr = len(recipients)
for email_chunk in split_every(50, recipients.ids):
# TDE FIXME: missing message parameter. So we will find mail_message_id
# in the mail_values and browse it. It should already be in the
# cache so should not impact performances.
mail_message_id = mail_values.get('mail_message_id')
message = self.env['mail.message'].browse(mail_message_id) if mail_message_id else None
if message and message.model and message.res_id and message.model in self.env and hasattr(self.env[message.model], 'message_get_recipient_values'):
tig = self.env[message.model].browse(message.res_id)
recipient_values = tig.message_get_recipient_values(notif_message=message, recipient_ids=email_chunk.ids)
recipient_values = tig.message_get_recipient_values(notif_message=message, recipient_ids=email_chunk)
else:
recipient_values = self.env['mail.thread'].message_get_recipient_values(notif_message=None, recipient_ids=email_chunk.ids)
recipient_values = self.env['mail.thread'].message_get_recipient_values(notif_message=None, recipient_ids=email_chunk)
create_values = {
'body_html': body,
'subject': subject,
Expand Down
Loading

0 comments on commit 2e6a589

Please sign in to comment.