diff --git a/odoo/fields.py b/odoo/fields.py index adeda5176b3..6ef211e12a8 100644 --- a/odoo/fields.py +++ b/odoo/fields.py @@ -58,14 +58,13 @@ def resolve_mro(model, name, predicate): classes are ignored. """ result = [] - for cls in type(model).mro(): - if not is_registry_class(cls): - value = cls.__dict__.get(name, Default) - if value is Default: - continue - if not predicate(value): - break - result.append(value) + for cls in model._model_classes: + value = cls.__dict__.get(name, Default) + if value is Default: + continue + if not predicate(value): + break + result.append(value) return result @@ -4100,6 +4099,6 @@ def apply_required(model, field_name): # pylint: disable=wrong-import-position from .exceptions import AccessError, MissingError, UserError from .models import ( - check_pg_name, expand_ids, is_definition_class, is_registry_class, + check_pg_name, expand_ids, is_definition_class, BaseModel, IdType, NewId, PREFETCH_MAX, ) diff --git a/odoo/models.py b/odoo/models.py index e4a954fdd26..29bfea68f5c 100644 --- a/odoo/models.py +++ b/odoo/models.py @@ -2986,6 +2986,12 @@ class BaseModel(metaclass=MetaModel): if cls._setup_done: return + # the classes that define this model, i.e., the ones that are not + # registry classes; the purpose of this attribute is to behave as a + # cache of [c for c in cls.mro() if not is_registry_class(c))], which + # is heavily used in function fields.resolve_mro() + cls._model_classes = tuple(c for c in cls.mro() if getattr(c, 'pool', None) is None) + # 1. determine the proper fields of the model: the fields defined on the # class and magic fields, not the inherited or custom ones @@ -2997,8 +3003,9 @@ class BaseModel(metaclass=MetaModel): # collect the definitions of each field (base definition + overrides) definitions = defaultdict(list) - for klass in reversed(cls.mro()): - if is_definition_class(klass): + for klass in reversed(cls._model_classes): + # this condition is an optimization of is_definition_class(klass) + if isinstance(klass, MetaModel): for field in klass._field_definitions: definitions[field.name].append(field) for name, fields_ in definitions.items():