r"""Decorate a method as a 'validator' for one or more named properties. Designates a method as a validator, a method which receives the name of the attribute as well as a value to be assigned, or in the case of a collection, the value to be added to the collection. The function can
(
*names: str, include_removes: bool = False, include_backrefs: bool = True
)
| 4344 | |
| 4345 | |
| 4346 | def validates( |
| 4347 | *names: str, include_removes: bool = False, include_backrefs: bool = True |
| 4348 | ) -> Callable[[_Fn], _Fn]: |
| 4349 | r"""Decorate a method as a 'validator' for one or more named properties. |
| 4350 | |
| 4351 | Designates a method as a validator, a method which receives the |
| 4352 | name of the attribute as well as a value to be assigned, or in the |
| 4353 | case of a collection, the value to be added to the collection. |
| 4354 | The function can then raise validation exceptions to halt the |
| 4355 | process from continuing (where Python's built-in ``ValueError`` |
| 4356 | and ``AssertionError`` exceptions are reasonable choices), or can |
| 4357 | modify or replace the value before proceeding. The function should |
| 4358 | otherwise return the given value. |
| 4359 | |
| 4360 | Note that a validator for a collection **cannot** issue a load of that |
| 4361 | collection within the validation routine - this usage raises |
| 4362 | an assertion to avoid recursion overflows. This is a reentrant |
| 4363 | condition which is not supported. |
| 4364 | |
| 4365 | :param \*names: list of attribute names to be validated. |
| 4366 | :param include_removes: if True, "remove" events will be |
| 4367 | sent as well - the validation function must accept an additional |
| 4368 | argument "is_remove" which will be a boolean. |
| 4369 | |
| 4370 | :param include_backrefs: defaults to ``True``; if ``False``, the |
| 4371 | validation function will not emit if the originator is an attribute |
| 4372 | event related via a backref. This can be used for bi-directional |
| 4373 | :func:`.validates` usage where only one validator should emit per |
| 4374 | attribute operation. |
| 4375 | |
| 4376 | .. versionchanged:: 2.0.16 This parameter inadvertently defaulted to |
| 4377 | ``False`` for releases 2.0.0 through 2.0.15. Its correct default |
| 4378 | of ``True`` is restored in 2.0.16. |
| 4379 | |
| 4380 | .. seealso:: |
| 4381 | |
| 4382 | :ref:`simple_validators` - usage examples for :func:`.validates` |
| 4383 | |
| 4384 | """ |
| 4385 | |
| 4386 | def wrap(fn: _Fn) -> _Fn: |
| 4387 | fn.__sa_validators__ = names # type: ignore[attr-defined] |
| 4388 | fn.__sa_validation_opts__ = { # type: ignore[attr-defined] |
| 4389 | "include_removes": include_removes, |
| 4390 | "include_backrefs": include_backrefs, |
| 4391 | } |
| 4392 | return fn |
| 4393 | |
| 4394 | return wrap |
| 4395 | |
| 4396 | |
| 4397 | def _event_on_load(state, ctx): |