diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2023-02-10 16:06:23 -0500 |
---|---|---|
committer | mike bayer <mike_mp@zzzcomputing.com> | 2023-02-16 00:09:14 +0000 |
commit | 18fd19e60d55b35408d94b892e0a2051bcb7ec88 (patch) | |
tree | af402c777c265c841e46147ad309c17671f0e252 /lib/sqlalchemy/orm/decl_api.py | |
parent | 8855656626202e541bd2c95bc023e820a022322f (diff) | |
download | sqlalchemy-18fd19e60d55b35408d94b892e0a2051bcb7ec88.tar.gz |
add dataclasses callable and apply annotations more strictly
Added new parameter ``dataclasses_callable`` to both the
:class:`_orm.MappedAsDataclass` class as well as the
:meth:`_orm.registry.mapped_as_dataclass` method which allows an
alternative callable to Python ``dataclasses.dataclass`` to be used in
order to produce dataclasses. The use case here is to drop in Pydantic's
dataclass function instead. Adjustments have been made to the mixin support
added for :ticket:`9179` in version 2.0.1 so that the ``__annotations__``
collection of the mixin is rewritten to not include the
:class:`_orm.Mapped` container, in the same way as occurs with mapped
classes, so that the Pydantic dataclasses constructor is not exposed to
unknown types.
Fixes: #9266
Change-Id: Ia0fab6f20b93a5cb853799dcf1b70a0386837c14
Diffstat (limited to 'lib/sqlalchemy/orm/decl_api.py')
-rw-r--r-- | lib/sqlalchemy/orm/decl_api.py | 14 |
1 files changed, 13 insertions, 1 deletions
diff --git a/lib/sqlalchemy/orm/decl_api.py b/lib/sqlalchemy/orm/decl_api.py index d02012b86..f332d2964 100644 --- a/lib/sqlalchemy/orm/decl_api.py +++ b/lib/sqlalchemy/orm/decl_api.py @@ -593,6 +593,9 @@ class MappedAsDataclass(metaclass=DCTransformDeclarative): unsafe_hash: Union[_NoArg, bool] = _NoArg.NO_ARG, match_args: Union[_NoArg, bool] = _NoArg.NO_ARG, kw_only: Union[_NoArg, bool] = _NoArg.NO_ARG, + dataclass_callable: Union[ + _NoArg, Callable[..., Type[Any]] + ] = _NoArg.NO_ARG, ) -> None: apply_dc_transforms: _DataclassArguments = { "init": init, @@ -602,6 +605,7 @@ class MappedAsDataclass(metaclass=DCTransformDeclarative): "unsafe_hash": unsafe_hash, "match_args": match_args, "kw_only": kw_only, + "dataclass_callable": dataclass_callable, } current_transforms: _DataclassArguments @@ -623,8 +627,11 @@ class MappedAsDataclass(metaclass=DCTransformDeclarative): super().__init_subclass__() if not _is_mapped_class(cls): + new_anno = ( + _ClassScanMapperConfig._update_annotations_for_non_mapped_class + )(cls) _ClassScanMapperConfig._apply_dataclasses_to_any_class( - current_transforms, cls + current_transforms, cls, new_anno ) @@ -1569,6 +1576,7 @@ class registry: unsafe_hash: Union[_NoArg, bool] = ..., match_args: Union[_NoArg, bool] = ..., kw_only: Union[_NoArg, bool] = ..., + dataclass_callable: Union[_NoArg, Callable[..., Type[Any]]] = ..., ) -> Callable[[Type[_O]], Type[_O]]: ... @@ -1583,6 +1591,9 @@ class registry: unsafe_hash: Union[_NoArg, bool] = _NoArg.NO_ARG, match_args: Union[_NoArg, bool] = _NoArg.NO_ARG, kw_only: Union[_NoArg, bool] = _NoArg.NO_ARG, + dataclass_callable: Union[ + _NoArg, Callable[..., Type[Any]] + ] = _NoArg.NO_ARG, ) -> Union[Type[_O], Callable[[Type[_O]], Type[_O]]]: """Class decorator that will apply the Declarative mapping process to a given class, and additionally convert the class to be a @@ -1608,6 +1619,7 @@ class registry: "unsafe_hash": unsafe_hash, "match_args": match_args, "kw_only": kw_only, + "dataclass_callable": dataclass_callable, } _as_declarative(self, cls, cls.__dict__) return cls |