Dynamically create a submodel of a provided (generic) BaseModel. This is used when producing concrete parametrizations of generic models. This function only *creates* the new subclass; the schema/validators/serialization must be updated to reflect a concrete parametrization elsewhere.
(
model_name: str, origin: type[BaseModel], args: tuple[Any, ...], params: tuple[Any, ...]
)
| 103 | |
| 104 | |
| 105 | def create_generic_submodel( |
| 106 | model_name: str, origin: type[BaseModel], args: tuple[Any, ...], params: tuple[Any, ...] |
| 107 | ) -> type[BaseModel]: |
| 108 | """Dynamically create a submodel of a provided (generic) BaseModel. |
| 109 | |
| 110 | This is used when producing concrete parametrizations of generic models. This function |
| 111 | only *creates* the new subclass; the schema/validators/serialization must be updated to |
| 112 | reflect a concrete parametrization elsewhere. |
| 113 | |
| 114 | Args: |
| 115 | model_name: The name of the newly created model. |
| 116 | origin: The base class for the new model to inherit from. |
| 117 | args: A tuple of generic metadata arguments. |
| 118 | params: A tuple of generic metadata parameters. |
| 119 | |
| 120 | Returns: |
| 121 | The created submodel. |
| 122 | """ |
| 123 | namespace: dict[str, Any] = {'__module__': origin.__module__} |
| 124 | bases = (origin,) |
| 125 | meta, ns, kwds = prepare_class(model_name, bases) |
| 126 | namespace.update(ns) |
| 127 | created_model = meta( |
| 128 | model_name, |
| 129 | bases, |
| 130 | namespace, |
| 131 | __pydantic_generic_metadata__={ |
| 132 | 'origin': origin, |
| 133 | 'args': args, |
| 134 | 'parameters': params, |
| 135 | }, |
| 136 | __pydantic_reset_parent_namespace__=False, |
| 137 | **kwds, |
| 138 | ) |
| 139 | |
| 140 | model_module, called_globally = _get_caller_frame_info(depth=3) |
| 141 | if called_globally: # create global reference and therefore allow pickling |
| 142 | object_by_reference = None |
| 143 | reference_name = model_name |
| 144 | reference_module_globals = sys.modules[created_model.__module__].__dict__ |
| 145 | while object_by_reference is not created_model: |
| 146 | object_by_reference = reference_module_globals.setdefault(reference_name, created_model) |
| 147 | reference_name += '_' |
| 148 | |
| 149 | return created_model |
| 150 | |
| 151 | |
| 152 | def _get_caller_frame_info(depth: int = 2) -> tuple[str | None, bool]: |
nothing calls this directly
no test coverage detected