Coverage for pyodmongo/models/metaclasses.py: 100%
28 statements
« prev ^ index » next coverage.py v7.6.10, created at 2025-01-16 15:08 +0000
« prev ^ index » next coverage.py v7.6.10, created at 2025-01-16 15:08 +0000
1from typing import Any
2from ..services.model_init import (
3 resolve_indexes,
4 resolve_class_fields_db_info,
5)
6from pydantic import BaseModel
7from pydantic._internal._model_construction import ModelMetaclass
8from typing_extensions import dataclass_transform
11@dataclass_transform(kw_only_default=True)
12class PyOdmongoMeta(ModelMetaclass):
13 """
14 Metaclass for creating and configuring PyODMongo models. This metaclass extends
15 the functionality of Pydantic's ModelMetaclass to include database-specific
16 configurations and transformations.
18 The primary responsibilities of this metaclass are:
19 - Setting and tracking the `__pyodmongo_complete__` attribute to ensure proper
20 initialization of database-related features.
21 - Applying necessary transformations to class fields for database compatibility.
22 - Providing custom attribute access behavior for dynamically generated attributes.
24 Attributes:
25 __pyodmongo_complete__ (bool): Indicator of whether the meta-level
26 configuration is complete.
28 Methods:
29 __new__(cls, name, bases, namespace, **kwargs): Constructs a new class instance,
30 applying database-specific initializations.
31 __getattr__(cls, name): Custom attribute access method supporting dynamic
32 attribute retrieval based on model fields.
33 """
35 def __new__(
36 cls, name: str, bases: tuple[Any], namespace: dict, **kwargs: Any
37 ) -> type:
38 setattr(cls, "__pyodmongo_complete__", False)
39 for base in bases:
40 setattr(base, "__pyodmongo_complete__", False)
42 cls: BaseModel = ModelMetaclass.__new__(cls, name, bases, namespace, **kwargs)
44 setattr(cls, "__pyodmongo_complete__", True)
45 for base in bases:
46 setattr(base, "__pyodmongo_complete__", True)
48 resolve_class_fields_db_info(cls=cls)
49 return cls
51 def __getattr__(cls, name: str):
52 if cls.__dict__.get("__pyodmongo_complete__") and cls.__dict__.get(
53 name + "__pyodmongo"
54 ):
55 return cls.__dict__.get(name + "__pyodmongo")
56 ModelMetaclass.__getattr__(cls, name)
59@dataclass_transform(kw_only_default=True)
60class DbMeta(PyOdmongoMeta):
61 """
62 Metaclass for database model entities in a PyODMongo environment. It extends
63 the functionality of the PyOdmongoMeta by applying specific behaviors and
64 transformations related to database operations such as indexing, reference
65 resolution, and initialization of database fields.
67 The primary responsibilities of this metaclass are:
68 - Constructing new class instances with additional database-specific adjustments
69 and initializations.
70 - Setting up pipelines for resolving references within the database context.
71 - Configuring indexes for efficient database operations.
73 Attributes:
74 __pyodmongo_complete__ (bool): Attribute used to track the completion of
75 the meta-level configuration.
77 Methods:
78 __new__(cls, name, bases, namespace, **kwargs): Constructs a new class instance,
79 ensuring database-specific adjustments and initializations are applied.
80 """
82 def __new__(
83 cls, name: str, bases: tuple[Any], namespace: dict, **kwargs: Any
84 ) -> type:
85 cls: BaseModel = PyOdmongoMeta.__new__(cls, name, bases, namespace, **kwargs)
87 indexes = resolve_indexes(cls=cls)
88 setattr(cls, "_init_indexes", indexes)
89 return cls