[FIX] fields: when computing digits, use an existing cursor instead of a new one

The computation of property `digits` was creating a new cursor to call the
function that determines digits.  This technique is fragile because the current
cursor may have pending updates that the new cursor will not see.

The issue was discovered by Cécile Tonglet (cto).  She observed an infinite
loop during a database migration, and a traceback inside the loop showed the
presence of the `digits` property.  This change fixes the infinite loop issue.
This commit is contained in:
Raphael Collet 2015-05-05 12:01:22 +02:00
parent 9d7b6aa67f
commit 071152216f
3 changed files with 18 additions and 8 deletions

View File

@ -68,7 +68,7 @@ from pprint import pformat
from weakref import WeakSet from weakref import WeakSet
from werkzeug.local import Local, release_local from werkzeug.local import Local, release_local
from openerp.tools import frozendict from openerp.tools import frozendict, classproperty
_logger = logging.getLogger(__name__) _logger = logging.getLogger(__name__)
@ -674,6 +674,10 @@ class Environment(object):
""" """
_local = Local() _local = Local()
@classproperty
def envs(cls):
return cls._local.environments
@classmethod @classmethod
@contextmanager @contextmanager
def manage(cls): def manage(cls):
@ -699,7 +703,7 @@ class Environment(object):
args = (cr, uid, context) args = (cr, uid, context)
# if env already exists, return it # if env already exists, return it
env, envs = None, cls._local.environments env, envs = None, cls.envs
for env in envs: for env in envs:
if env.args == args: if env.args == args:
return env return env

View File

@ -1054,8 +1054,10 @@ class Float(Field):
@property @property
def digits(self): def digits(self):
if callable(self._digits): if callable(self._digits):
with registry().cursor() as cr: # retrieve a cursor from any environment
return self._digits(cr) from openerp.api import Environment
cr = next(iter(Environment.envs)).cr
return self._digits(cr)
else: else:
return self._digits return self._digits

View File

@ -388,8 +388,10 @@ class float(_column):
@property @property
def digits(self): def digits(self):
if self._digits_compute: if self._digits_compute:
with registry().cursor() as cr: # retrieve a cursor from any environment
return self._digits_compute(cr) from openerp.api import Environment
cr = next(iter(Environment.envs)).cr
return self._digits_compute(cr)
else: else:
return self._digits return self._digits
@ -1309,8 +1311,10 @@ class function(_column):
@property @property
def digits(self): def digits(self):
if self._digits_compute: if self._digits_compute:
with registry().cursor() as cr: # retrieve a cursor from any environment
return self._digits_compute(cr) from openerp.api import Environment
cr = next(iter(Environment.envs)).cr
return self._digits_compute(cr)
else: else:
return self._digits return self._digits