From 9f09c625f5163ef98ee308ea1bd7cb2004ef1f03 Mon Sep 17 00:00:00 2001 From: Martin Geubelle Date: Fri, 28 Oct 2016 10:48:01 +0200 Subject: [PATCH 1/3] [FIX] calendar: rule._bynweekday can be a set Depending on the version of dateutil, rule._bynweekday can either be a tuple or a set (see https://github.com/dateutil/dateutil/pull/54), which, in the case of a set, breaks the access by index (see related issue: https://github.com/dateutil/dateutil/issues/24). By casting it into a list, we make sure that we can access [0] in both case. Credits to jke ; closes opw-690761. --- addons/calendar/calendar.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/calendar/calendar.py b/addons/calendar/calendar.py index 0c38539d677..3e714243641 100644 --- a/addons/calendar/calendar.py +++ b/addons/calendar/calendar.py @@ -1343,8 +1343,8 @@ class calendar_event(osv.Model): data['rrule_type'] = 'weekly' #repeat monthly by nweekday ((weekday, weeknumber), ) if r._bynweekday: - data['week_list'] = day_list[r._bynweekday[0][0]].upper() - data['byday'] = str(r._bynweekday[0][1]) + data['week_list'] = day_list[list(r._bynweekday)[0][0]].upper() + data['byday'] = str(list(r._bynweekday)[0][1]) data['month_by'] = 'day' data['rrule_type'] = 'monthly' From eb326e669e991e5dadfa6a4aa3245b7077613821 Mon Sep 17 00:00:00 2001 From: Raphael Collet Date: Wed, 26 Oct 2016 10:51:23 +0200 Subject: [PATCH 2/3] [FIX] fields: prevent base setup on fields shared across registries A field shared across registries is normally never setup from scratch, except when its full setup cannot complete. This happens when a registry reuses that field but fails to load, because the base and full setup of fields look like: def setup_base(self, model, name): if self.setup_full_done: # optimization: keep base setup (1) self.setup_full_done = False else: # do the base setup from scratch (2) ... def setup_full(self, model): if not self.setup_full_done: # complete full setup (3) self.setup_full_done = True When the field is reused for the first time, its setup state `setup_full_done` is reset to `False` (1), and it should be set to `True` again after completion of full setup (3). However, because the full setup fails, the field remains with `setup_full_done` equal to `False`. In that situation, when the same field is reused again, it base setup will be done from scratch (2), and therefore some attributes (like `column`) are reset to their initial value. Because the full setup fails again, those attributes are lost for other registries that share the field. Fix this crap by precising the setup states: `None`, `'base'` and `'full'`. When a field is reused, its setup state is reset to `'base'` instead of `None`, and consequently it will never be setup from scratch again. --- openerp/fields.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/openerp/fields.py b/openerp/fields.py index 81a3acf2743..6ccc6325f83 100644 --- a/openerp/fields.py +++ b/openerp/fields.py @@ -304,7 +304,7 @@ class Field(object): _slots = { 'args': EMPTY_DICT, # the parameters given to __init__() '_attrs': EMPTY_DICT, # the field's non-slot attributes - 'setup_full_done': False, # whether the field has been fully setup + '_setup_done': None, # the field's setup state: None, 'base' or 'full' 'automatic': False, # whether the field is automatically created ("magic" field) 'inherited': False, # whether the field is inherited (_inherits) @@ -346,7 +346,7 @@ class Field(object): kwargs['string'] = string args = {key: val for key, val in kwargs.iteritems() if val is not None} self.args = args or EMPTY_DICT - self.setup_full_done = False + self._setup_done = None def new(self, **kwargs): """ Return a field of the same type as ``self``, with its own parameters. """ @@ -398,14 +398,15 @@ class Field(object): def setup_base(self, model, name): """ Base setup: things that do not depend on other models/fields. """ - if self.setup_full_done and not self.related: + if self._setup_done and not self.related: # optimization for regular fields: keep the base setup - self.setup_full_done = False + self._setup_done = 'base' else: # do the base setup from scratch self._setup_attrs(model, name) if not self.related: self._setup_regular_base(model) + self._setup_done = 'base' # # Setup field parameter attributes @@ -490,12 +491,12 @@ class Field(object): def setup_full(self, model): """ Full setup: everything else, except recomputation triggers. """ - if not self.setup_full_done: + if self._setup_done != 'full': if not self.related: self._setup_regular_full(model) else: self._setup_related_full(model) - self.setup_full_done = True + self._setup_done = 'full' # # Setup of non-related fields From c39ca45c6de4124d5301c7bcfbdc286a1d7d934d Mon Sep 17 00:00:00 2001 From: Wolfgang Taferner Date: Fri, 28 Oct 2016 13:41:11 +0200 Subject: [PATCH 3/3] [FIX] config: avoid to accept server-wide-modules with None as a module Fixes #14048 Fixes #14045 Closes #14051 --- openerp/tools/config.py | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/openerp/tools/config.py b/openerp/tools/config.py index 70b70900b60..f1dd6251036 100644 --- a/openerp/tools/config.py +++ b/openerp/tools/config.py @@ -142,7 +142,7 @@ class configmanager(object): group.add_option("--addons-path", dest="addons_path", help="specify additional addons paths (separated by commas).", action="callback", callback=self._check_addons_path, nargs=1, type="string") - group.add_option("--load", dest="server_wide_modules", help="Comma-separated list of server-wide modules. Default is 'web,web_kanban'") + group.add_option("--load", dest="server_wide_modules", help="Comma-separated list of server-wide modules.", my_default='web,web_kanban') group.add_option("-D", "--data-dir", dest="data_dir", my_default=_get_default_datadir(), help="Directory where to store Odoo data") @@ -408,6 +408,9 @@ class configmanager(object): # the same for the pidfile if self.options['pidfile'] in ('None', 'False'): self.options['pidfile'] = False + # and the server_wide_modules + if self.options['server_wide_modules'] in ('', 'None', 'False'): + self.options['server_wide_modules'] = 'web,web_kanban' # if defined dont take the configfile value even if the defined value is None keys = ['xmlrpc_interface', 'xmlrpc_port', 'longpolling_port', @@ -530,20 +533,13 @@ class configmanager(object): #if self.options['db_host']: # self._generate_pgpassfile() - # server_wide_modules defaults to web,web_kanban if empty or unset - server_wide_modules = self.options['server_wide_modules'] = ( - self.options['server_wide_modules'] - if self.options['server_wide_modules'] - else 'web,web_kanban' - ) - if opt.save: self.save() openerp.conf.addons_paths = self.options['addons_path'].split(',') openerp.conf.server_wide_modules = [ - m.strip() for m in server_wide_modules.split(',') + m.strip() for m in self.options['server_wide_modules'].split(',') if m.strip() ] def _generate_pgpassfile(self):