Skip to content

Commit

Permalink
Better control of model rebuild
Browse files Browse the repository at this point in the history
The model only needs to be rebuilt when the resolution of field types in an extensible model modifies the field type. This modification only occurs if the field is itself of an extensible type. In this case, the original type is replaced by the class aggregated for the original type.
  • Loading branch information
lmignon committed Nov 21, 2023
1 parent 8f9fb77 commit 46184ef
Showing 1 changed file with 6 additions and 12 deletions.
18 changes: 6 additions & 12 deletions src/extendable_pydantic/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import inspect
import typing
import warnings
from typing import Any, Dict, List, Optional, cast, no_type_check, Set
from typing import Any, Dict, List, Optional, cast, no_type_check

from extendable import context, main
from extendable.main import ExtendableMeta
Expand All @@ -28,6 +28,8 @@


class ExtendableModelMeta(ExtendableMeta, ModelMetaclass):
__xreg_fields_resolved__: bool = False

@no_type_check
@classmethod
def _build_original_class(metacls, name, bases, namespace, **kwargs):
Expand All @@ -45,6 +47,7 @@ def _prepare_namespace(
namespace = super()._prepare_namespace(
name=name, bases=bases, namespace=namespace, extends=extends, **kwargs
)
namespace["__xreg_fields_resolved__"] = False
return namespace

@no_type_check
Expand Down Expand Up @@ -93,13 +96,9 @@ def _resolve_submodel_fields(
"""Replace the original field type into the definition of the field by the one
from the registry."""
registry = registry if registry else context.extendable_registry.get()
resolved: Set["ExtendableModelMeta"] = getattr(
registry, "_resolved_models", set()
)
if cls in resolved:
if cls.__xreg_fields_resolved__:
return
resolved.add(cls)
registry._resolved_models = resolved # type: ignore[union-attr]
cls.__xreg_fields_resolved__ = True
to_rebuild = False
if issubclass(cls, BaseModel):
for field_name, field_info in cast(BaseModel, cls).model_fields.items():
Expand All @@ -117,7 +116,6 @@ def _resolve_submodel_fields(
class RegistryListener(ExtendableRegistryListener):
def on_registry_initialized(self, registry: ExtendableClassesRegistry) -> None:
self.resolve_submodel_fields(registry)
self.rebuild_models(registry)

def before_init_registry(
self,
Expand All @@ -130,10 +128,6 @@ def before_init_registry(
if "extendable_pydantic" not in module_matchings:
module_matchings.insert(0, "extendable_pydantic.models")

def rebuild_models(self, registry: ExtendableClassesRegistry) -> None:
for cls in registry._extendable_classes.values():
cast(BaseModel, cls).model_rebuild(force=True)

def resolve_submodel_fields(self, registry: ExtendableClassesRegistry) -> None:
for cls in registry._extendable_classes.values():
if issubclass(type(cls), ExtendableModelMeta):
Expand Down

0 comments on commit 46184ef

Please sign in to comment.