arpakitlib 1.8.225__py3-none-any.whl → 1.8.226__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- arpakitlib/clone_pydantic_model_fields.py +3 -0
- arpakitlib/pydantic_schema_from_sqlalchemy_model.py +2 -0
- arpakitlib/raise_own_exception_if_exception.py +95 -0
- {arpakitlib-1.8.225.dist-info → arpakitlib-1.8.226.dist-info}/METADATA +1 -1
- {arpakitlib-1.8.225.dist-info → arpakitlib-1.8.226.dist-info}/RECORD +8 -7
- {arpakitlib-1.8.225.dist-info → arpakitlib-1.8.226.dist-info}/LICENSE +0 -0
- {arpakitlib-1.8.225.dist-info → arpakitlib-1.8.226.dist-info}/WHEEL +0 -0
- {arpakitlib-1.8.225.dist-info → arpakitlib-1.8.226.dist-info}/entry_points.txt +0 -0
@@ -1,3 +1,4 @@
|
|
1
|
+
# arpakit
|
1
2
|
import datetime as dt
|
2
3
|
from typing import Any, Optional
|
3
4
|
|
@@ -10,6 +11,7 @@ from sqlalchemy.sql.sqltypes import (
|
|
10
11
|
DateTime, Date, Time,
|
11
12
|
Float, Numeric, DECIMAL, LargeBinary, JSON
|
12
13
|
)
|
14
|
+
_ARPAKIT_LIB_MODULE_VERSION = "3.0"
|
13
15
|
|
14
16
|
_SQLA_TYPE_MAP = {
|
15
17
|
Boolean: bool,
|
@@ -0,0 +1,95 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
import inspect
|
4
|
+
from functools import wraps
|
5
|
+
from typing import Any, Callable, Awaitable, Tuple, TypeVar, ParamSpec, cast
|
6
|
+
|
7
|
+
_ARPAKIT_LIB_MODULE_VERSION = "3.0"
|
8
|
+
|
9
|
+
PARAMS_SPEC = ParamSpec("PARAMS_SPEC")
|
10
|
+
RESULT_SPEC = TypeVar("RESULT_SPEC")
|
11
|
+
|
12
|
+
|
13
|
+
def raise_own_exception_if_exception(
|
14
|
+
*,
|
15
|
+
catching_exceptions: type[BaseException] | Tuple[type[BaseException], ...] | None = Exception,
|
16
|
+
except_catching_exceptions: type[BaseException] | Tuple[type[BaseException], ...] | None = None,
|
17
|
+
own_exception: type[Exception],
|
18
|
+
kwargs_in_own_exception: dict[str, Any] | None = None,
|
19
|
+
) -> (
|
20
|
+
Callable[[Callable[PARAMS_SPEC, RESULT_SPEC] | Callable[PARAMS_SPEC, Awaitable[RESULT_SPEC]]],
|
21
|
+
Callable[PARAMS_SPEC, RESULT_SPEC] | Callable[PARAMS_SPEC, Awaitable[RESULT_SPEC]]]
|
22
|
+
):
|
23
|
+
"""
|
24
|
+
Ловит любые Exception и оборачивает в own_exception(**kwargs_).
|
25
|
+
Исключения из except_exceptions пропускает как есть.
|
26
|
+
Работает и для sync, и для async функций.
|
27
|
+
"""
|
28
|
+
|
29
|
+
# normalize catching_exceptions -> tuple[type, ...]
|
30
|
+
if catching_exceptions is None:
|
31
|
+
catching_exceptions = (Exception,)
|
32
|
+
elif isinstance(catching_exceptions, tuple):
|
33
|
+
catching_exceptions = catching_exceptions
|
34
|
+
else:
|
35
|
+
catching_exceptions = (catching_exceptions,)
|
36
|
+
|
37
|
+
# Нормализуем except_exceptions к кортежу типов
|
38
|
+
if except_catching_exceptions is None:
|
39
|
+
except_catching_exceptions = ()
|
40
|
+
elif isinstance(except_catching_exceptions, tuple):
|
41
|
+
except_catching_exceptions = except_catching_exceptions
|
42
|
+
elif except_catching_exceptions:
|
43
|
+
except_catching_exceptions = (except_catching_exceptions,)
|
44
|
+
else:
|
45
|
+
except_catching_exceptions = ()
|
46
|
+
|
47
|
+
kwargs_in_own_exception = dict(kwargs_in_own_exception or {})
|
48
|
+
kwargs_in_own_exception["catching_exceptions"] = catching_exceptions
|
49
|
+
kwargs_in_own_exception["except_catching_exceptions"] = except_catching_exceptions
|
50
|
+
kwargs_in_own_exception["own_exception"] = own_exception
|
51
|
+
|
52
|
+
# Если явно передали пустой набор для ловли — возвращаем функцию как есть
|
53
|
+
if not catching_exceptions:
|
54
|
+
def _passthrough_decorator(func):
|
55
|
+
return func
|
56
|
+
|
57
|
+
return _passthrough_decorator
|
58
|
+
|
59
|
+
def decorator(func: Callable[PARAMS_SPEC, RESULT_SPEC] | Callable[PARAMS_SPEC, Awaitable[RESULT_SPEC]]):
|
60
|
+
if inspect.iscoroutinefunction(func):
|
61
|
+
@wraps(func)
|
62
|
+
async def async_wrapper(*args: PARAMS_SPEC.args, **kwargs: PARAMS_SPEC.kwargs) -> RESULT_SPEC:
|
63
|
+
try:
|
64
|
+
return await cast(Callable[PARAMS_SPEC, Awaitable[RESULT_SPEC]], func)(*args, **kwargs)
|
65
|
+
except catching_exceptions as caught_exception: # ловим ТОЛЬКО нужные типы
|
66
|
+
if except_catching_exceptions and isinstance(caught_exception, except_catching_exceptions):
|
67
|
+
raise # пропускаем как есть
|
68
|
+
copied_kwargs_in_own_exception = kwargs_in_own_exception.copy()
|
69
|
+
copied_kwargs_in_own_exception["caught_exception"] = caught_exception
|
70
|
+
copied_kwargs_in_own_exception["caught_exception_str"] = str(caught_exception)
|
71
|
+
try:
|
72
|
+
raise own_exception(kwargs_=copied_kwargs_in_own_exception) from caught_exception
|
73
|
+
except TypeError:
|
74
|
+
raise own_exception() from caught_exception
|
75
|
+
|
76
|
+
return cast(Callable[PARAMS_SPEC, Awaitable[RESULT_SPEC]], async_wrapper)
|
77
|
+
|
78
|
+
@wraps(func)
|
79
|
+
def wrapper(*args: PARAMS_SPEC.args, **kwargs: PARAMS_SPEC.kwargs) -> RESULT_SPEC:
|
80
|
+
try:
|
81
|
+
return cast(Callable[PARAMS_SPEC, RESULT_SPEC], func)(*args, **kwargs)
|
82
|
+
except catching_exceptions as caught_exception:
|
83
|
+
if except_catching_exceptions and isinstance(caught_exception, except_catching_exceptions):
|
84
|
+
raise
|
85
|
+
copied_kwargs_in_own_exception = kwargs_in_own_exception.copy()
|
86
|
+
copied_kwargs_in_own_exception["caught_exception"] = caught_exception
|
87
|
+
copied_kwargs_in_own_exception["caught_exception_str"] = str(caught_exception)
|
88
|
+
try:
|
89
|
+
raise own_exception(kwargs_=copied_kwargs_in_own_exception) from caught_exception
|
90
|
+
except TypeError:
|
91
|
+
raise own_exception() from caught_exception
|
92
|
+
|
93
|
+
return cast(Callable[PARAMS_SPEC, RESULT_SPEC], wrapper)
|
94
|
+
|
95
|
+
return decorator
|
@@ -415,10 +415,11 @@ arpakitlib/ar_sqlalchemy_util.py,sha256=aNHK7kT1VNSHmGx8m6KsaLOZ9ofO7pFa10rW4vZe
|
|
415
415
|
arpakitlib/ar_str_util.py,sha256=2lGpnXDf2h1cBZpVf5i1tX_HCv5iBd6IGnrCw4QWWlY,4350
|
416
416
|
arpakitlib/ar_type_util.py,sha256=Cs_tef-Fc5xeyAF54KgISCsP11NHyzIsglm4S3Xx7iM,4049
|
417
417
|
arpakitlib/ar_yookassa_api_client_util.py,sha256=VozuZeCJjmLd1zj2BdC9WfiAQ3XYOrIMsdpNK-AUlm0,5347
|
418
|
-
arpakitlib/clone_pydantic_model_fields.py,sha256=
|
419
|
-
arpakitlib/pydantic_schema_from_sqlalchemy_model.py,sha256=
|
420
|
-
arpakitlib
|
421
|
-
arpakitlib-1.8.
|
422
|
-
arpakitlib-1.8.
|
423
|
-
arpakitlib-1.8.
|
424
|
-
arpakitlib-1.8.
|
418
|
+
arpakitlib/clone_pydantic_model_fields.py,sha256=xxLwtvJzDf8EWMvBE4psWIj8c-cyeCxLRX76oCY_4zk,1214
|
419
|
+
arpakitlib/pydantic_schema_from_sqlalchemy_model.py,sha256=_5Y79kQ4lLIOL6_afIFVwxY1EXzTMpi-veRR-WkPFOs,2879
|
420
|
+
arpakitlib/raise_own_exception_if_exception.py,sha256=XfLYQzfStHJMlaqCOvRuXZBRzcUn2Cj2a-vKJ_hspf8,4686
|
421
|
+
arpakitlib-1.8.226.dist-info/LICENSE,sha256=GPEDQMam2r7FSTYqM1mm7aKnxLaWcBotH7UvQtea-ec,11355
|
422
|
+
arpakitlib-1.8.226.dist-info/METADATA,sha256=rYAW_KpprE59zdjhtSM_hTkmWIfIYd_Oo6xBLZBmyc0,3741
|
423
|
+
arpakitlib-1.8.226.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
424
|
+
arpakitlib-1.8.226.dist-info/entry_points.txt,sha256=36xqR3PJFT2kuwjkM_EqoIy0qFUDPKSm_mJaI7emewE,87
|
425
|
+
arpakitlib-1.8.226.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|