[FIX] registry: use a unique list of models to load per module

This is necessary to preserve the model loading order
as defined in the module. This was broken when the 
metaclass was introduced to make the explicit model
constructor call optional.
One consequence is that the order in which the classes
are declared in the module really defines their
initialization order, even if the constructors are 
later called explcitly in a different order.
This latter case should be fairly rare, and easy to
fix too - simply putting the class declaration in the
right order.

bzr revid: odo@openerp.com-20110826161736-lgnpurtbcqtbseey
This commit is contained in:
Olivier Dony 2011-08-26 18:17:36 +02:00
parent e03849bb35
commit 3f00bfc405
2 changed files with 9 additions and 19 deletions

View File

@ -70,15 +70,10 @@ class Registry(object):
res = []
# Instanciate classes registered through their constructor and
# add them to the pool.
for klass in openerp.osv.orm.module_class_list.get(module, []):
res.append(klass.createInstance(self, cr))
# Instanciate classes automatically discovered.
# Instantiate registered classes (via metamodel discovery or via explicit
# constructor call), and add them to the pool.
for cls in openerp.osv.orm.MetaModel.module_to_models.get(module, []):
if cls not in openerp.osv.orm.module_class_list.get(module, []):
res.append(cls.createInstance(self, cr))
res.append(cls.createInstance(self, cr))
return res

View File

@ -70,9 +70,6 @@ from openerp.tools import SKIPPED_ELEMENT_TYPES
regex_order = re.compile('^(([a-z0-9_]+|"[a-z0-9_]+")( *desc| *asc)?( *, *|))+$', re.I)
regex_object_name = re.compile(r'^[a-z0-9_.]+$')
# Mapping between openerp module names and their osv classes.
module_class_list = {}
# Super-user identifier (aka Administrator aka root)
ROOT_USER_ID = 1
@ -806,23 +803,21 @@ class orm_template(object):
return obj
def __new__(cls):
""" Register this model.
"""Register this model.
This doesn't create an instance but simply register the model
as being part of the module where it is defined.
TODO make it possible to not even have to call the constructor
to be registered.
"""
# Set the module name (e.g. base, sale, accounting, ...) on the class.
module = cls.__module__.split('.')[0]
if not hasattr(cls, '_module'):
cls._module = module
# Remember which models to instanciate for this module.
module_class_list.setdefault(cls._module, []).append(cls)
# Record this class in the list of models to instantiate for this module,
# managed by the metaclass.
module_model_list = MetaModel.module_to_models.setdefault(cls._module, [])
if cls not in module_model_list:
module_model_list.append(cls)
# Since we don't return an instance here, the __init__
# method won't be called.