apexdevkit 1.22.2__tar.gz → 1.23.2__tar.gz
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.
- {apexdevkit-1.22.2 → apexdevkit-1.23.2}/PKG-INFO +2 -2
- {apexdevkit-1.22.2 → apexdevkit-1.23.2}/apexdevkit/annotation/deprecate.py +6 -6
- {apexdevkit-1.22.2 → apexdevkit-1.23.2}/apexdevkit/error.py +2 -1
- {apexdevkit-1.22.2 → apexdevkit-1.23.2}/apexdevkit/fastapi/builder.py +3 -2
- {apexdevkit-1.22.2 → apexdevkit-1.23.2}/apexdevkit/fastapi/dependable.py +3 -2
- {apexdevkit-1.22.2 → apexdevkit-1.23.2}/apexdevkit/fastapi/resource.py +2 -1
- {apexdevkit-1.22.2 → apexdevkit-1.23.2}/apexdevkit/fastapi/response.py +2 -1
- {apexdevkit-1.22.2 → apexdevkit-1.23.2}/apexdevkit/fastapi/schema.py +6 -5
- {apexdevkit-1.22.2 → apexdevkit-1.23.2}/apexdevkit/fastapi/service.py +4 -4
- {apexdevkit-1.22.2 → apexdevkit-1.23.2}/apexdevkit/fluent.py +2 -1
- {apexdevkit-1.22.2 → apexdevkit-1.23.2}/apexdevkit/formatter.py +3 -4
- {apexdevkit-1.22.2 → apexdevkit-1.23.2}/apexdevkit/http/fluent.py +5 -5
- {apexdevkit-1.22.2 → apexdevkit-1.23.2}/apexdevkit/http/httpx/client.py +2 -1
- {apexdevkit-1.22.2 → apexdevkit-1.23.2}/apexdevkit/id.py +2 -2
- {apexdevkit-1.22.2 → apexdevkit-1.23.2}/apexdevkit/query/generator.py +2 -1
- {apexdevkit-1.22.2 → apexdevkit-1.23.2}/apexdevkit/query/query.py +1 -1
- {apexdevkit-1.22.2 → apexdevkit-1.23.2}/apexdevkit/repository/base.py +2 -1
- {apexdevkit-1.22.2 → apexdevkit-1.23.2}/apexdevkit/repository/connector.py +11 -11
- {apexdevkit-1.22.2 → apexdevkit-1.23.2}/apexdevkit/repository/database.py +4 -2
- {apexdevkit-1.22.2 → apexdevkit-1.23.2}/apexdevkit/repository/decorator.py +2 -1
- {apexdevkit-1.22.2 → apexdevkit-1.23.2}/apexdevkit/repository/in_memory.py +8 -7
- {apexdevkit-1.22.2 → apexdevkit-1.23.2}/apexdevkit/repository/interface.py +2 -2
- {apexdevkit-1.22.2 → apexdevkit-1.23.2}/apexdevkit/repository/mssql.py +12 -15
- {apexdevkit-1.22.2 → apexdevkit-1.23.2}/apexdevkit/repository/repository.py +21 -8
- {apexdevkit-1.22.2 → apexdevkit-1.23.2}/apexdevkit/repository/sql.py +13 -13
- {apexdevkit-1.22.2 → apexdevkit-1.23.2}/apexdevkit/repository/sqlite.py +9 -8
- {apexdevkit-1.22.2 → apexdevkit-1.23.2}/apexdevkit/server.py +2 -1
- {apexdevkit-1.22.2 → apexdevkit-1.23.2}/apexdevkit/synchronization.py +2 -1
- {apexdevkit-1.22.2 → apexdevkit-1.23.2}/apexdevkit/testing/database.py +3 -3
- {apexdevkit-1.22.2 → apexdevkit-1.23.2}/apexdevkit/testing/fake.py +13 -13
- {apexdevkit-1.22.2 → apexdevkit-1.23.2}/apexdevkit/testing/rest.py +2 -1
- {apexdevkit-1.22.2 → apexdevkit-1.23.2}/pyproject.toml +31 -12
- {apexdevkit-1.22.2 → apexdevkit-1.23.2}/LICENSE +0 -0
- {apexdevkit-1.22.2 → apexdevkit-1.23.2}/README.md +0 -0
- {apexdevkit-1.22.2 → apexdevkit-1.23.2}/apexdevkit/__init__.py +0 -0
- {apexdevkit-1.22.2 → apexdevkit-1.23.2}/apexdevkit/annotation/__init__.py +0 -0
- {apexdevkit-1.22.2 → apexdevkit-1.23.2}/apexdevkit/environment.py +0 -0
- {apexdevkit-1.22.2 → apexdevkit-1.23.2}/apexdevkit/fastapi/__init__.py +0 -0
- {apexdevkit-1.22.2 → apexdevkit-1.23.2}/apexdevkit/fastapi/docs.py +0 -0
- {apexdevkit-1.22.2 → apexdevkit-1.23.2}/apexdevkit/fastapi/name.py +0 -0
- {apexdevkit-1.22.2 → apexdevkit-1.23.2}/apexdevkit/fastapi/request.py +0 -0
- {apexdevkit-1.22.2 → apexdevkit-1.23.2}/apexdevkit/fastapi/router.py +0 -0
- {apexdevkit-1.22.2 → apexdevkit-1.23.2}/apexdevkit/http/__init__.py +0 -0
- {apexdevkit-1.22.2 → apexdevkit-1.23.2}/apexdevkit/http/fake.py +0 -0
- {apexdevkit-1.22.2 → apexdevkit-1.23.2}/apexdevkit/http/httpx/__init__.py +0 -0
- {apexdevkit-1.22.2 → apexdevkit-1.23.2}/apexdevkit/http/httpx/hooks.py +0 -0
- {apexdevkit-1.22.2 → apexdevkit-1.23.2}/apexdevkit/http/json.py +0 -0
- {apexdevkit-1.22.2 → apexdevkit-1.23.2}/apexdevkit/http/url.py +0 -0
- {apexdevkit-1.22.2 → apexdevkit-1.23.2}/apexdevkit/key_fn.py +0 -0
- {apexdevkit-1.22.2 → apexdevkit-1.23.2}/apexdevkit/py.typed +0 -0
- {apexdevkit-1.22.2 → apexdevkit-1.23.2}/apexdevkit/query/__init__.py +0 -0
- {apexdevkit-1.22.2 → apexdevkit-1.23.2}/apexdevkit/repository/__init__.py +0 -0
- {apexdevkit-1.22.2 → apexdevkit-1.23.2}/apexdevkit/testing/__init__.py +0 -0
- {apexdevkit-1.22.2 → apexdevkit-1.23.2}/apexdevkit/value.py +0 -0
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: apexdevkit
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.23.2
|
|
4
4
|
Summary: Apex Development Tools for python.
|
|
5
5
|
Author: Apex Dev
|
|
6
6
|
Author-email: dev@apex.ge
|
|
7
|
-
Requires-Python: >=3.11
|
|
7
|
+
Requires-Python: >=3.11
|
|
8
8
|
Classifier: Programming Language :: Python :: 3
|
|
9
9
|
Classifier: Programming Language :: Python :: 3.11
|
|
10
10
|
Classifier: Programming Language :: Python :: 3.12
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import inspect
|
|
2
|
-
from
|
|
2
|
+
from collections.abc import Callable
|
|
3
|
+
from typing import Any, TypeVar, cast
|
|
3
4
|
from warnings import warn
|
|
4
5
|
|
|
5
6
|
F = TypeVar("F", bound=Callable[..., Any])
|
|
@@ -23,12 +24,11 @@ def deprecated(warning: str) -> Callable[[F], F]:
|
|
|
23
24
|
def decorator(obj: F) -> F:
|
|
24
25
|
if inspect.isfunction(obj) or inspect.ismethod(obj):
|
|
25
26
|
return cast(F, _wrap_function(obj, warning))
|
|
26
|
-
|
|
27
|
+
if inspect.isclass(obj):
|
|
27
28
|
return cast(F, _deprecate_class(obj, warning))
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
) # pragma: no cover
|
|
29
|
+
raise TypeError(
|
|
30
|
+
f"Unsupported type for deprecation: {type(obj)}"
|
|
31
|
+
) # pragma: no cover
|
|
32
32
|
|
|
33
33
|
return decorator
|
|
34
34
|
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
from abc import ABC, abstractmethod
|
|
4
|
+
from collections.abc import Mapping
|
|
4
5
|
from dataclasses import dataclass, field
|
|
5
|
-
from typing import Any,
|
|
6
|
+
from typing import Any, Self
|
|
6
7
|
|
|
7
8
|
from fastapi import APIRouter, FastAPI
|
|
8
9
|
from starlette.middleware.cors import CORSMiddleware
|
|
@@ -19,7 +20,7 @@ class FastApiBuilder:
|
|
|
19
20
|
def build(self) -> FastAPI:
|
|
20
21
|
self.app.add_exception_handler(
|
|
21
22
|
ApiError,
|
|
22
|
-
lambda
|
|
23
|
+
lambda _, exc: JSONResponse(content=exc.data, status_code=exc.code),
|
|
23
24
|
)
|
|
24
25
|
return self.app
|
|
25
26
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
from collections.abc import Callable
|
|
1
2
|
from dataclasses import dataclass
|
|
2
|
-
from typing import Annotated, Any,
|
|
3
|
+
from typing import Annotated, Any, Protocol
|
|
3
4
|
|
|
4
5
|
from fastapi import Depends, Path
|
|
5
6
|
from fastapi.requests import Request
|
|
@@ -52,7 +53,7 @@ class ParentDependency:
|
|
|
52
53
|
try:
|
|
53
54
|
return builder.with_parent(parent_id)
|
|
54
55
|
except DoesNotExistError as e:
|
|
55
|
-
raise ApiError(404, RestfulResponse(self.parent).not_found(e))
|
|
56
|
+
raise ApiError(404, RestfulResponse(self.parent).not_found(e)) from e
|
|
56
57
|
|
|
57
58
|
return Annotated[RestfulServiceBuilder, Depends(_)]
|
|
58
59
|
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
from abc import ABC, abstractmethod
|
|
2
|
+
from collections.abc import Callable, Iterable
|
|
2
3
|
from dataclasses import dataclass
|
|
3
4
|
from functools import cached_property
|
|
4
|
-
from typing import Any
|
|
5
|
+
from typing import Any
|
|
5
6
|
|
|
6
7
|
from pydantic import BaseModel, create_model
|
|
7
8
|
|
|
@@ -39,10 +40,10 @@ class RestfulSchema:
|
|
|
39
40
|
)
|
|
40
41
|
|
|
41
42
|
self._schema_for("Item", {self.name.singular: schema})
|
|
42
|
-
self._schema_for("Collection", {self.name.plural:
|
|
43
|
-
self._schema_for("CreateMany", {self.name.plural:
|
|
44
|
-
self._schema_for("UpdateMany", {self.name.plural:
|
|
45
|
-
self._schema_for("ReplaceMany", {self.name.plural:
|
|
43
|
+
self._schema_for("Collection", {self.name.plural: list[schema], "count": int})
|
|
44
|
+
self._schema_for("CreateMany", {self.name.plural: list[create_schema]})
|
|
45
|
+
self._schema_for("UpdateMany", {self.name.plural: list[update_many_item]})
|
|
46
|
+
self._schema_for("ReplaceMany", {self.name.plural: list[replace_schema]})
|
|
46
47
|
|
|
47
48
|
def _schema_for(self, action: str, fields: dict[str, Any]) -> type[BaseModel]:
|
|
48
49
|
if action not in self.schemas:
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from abc import
|
|
3
|
+
from collections.abc import Iterable, Mapping
|
|
4
4
|
from dataclasses import dataclass
|
|
5
5
|
from functools import cached_property
|
|
6
|
-
from typing import Any,
|
|
6
|
+
from typing import Any, Generic, TypeVar
|
|
7
7
|
|
|
8
8
|
from apexdevkit.formatter import Formatter
|
|
9
9
|
from apexdevkit.query.query import FooterOptions, QueryOptions, Summary
|
|
@@ -14,7 +14,7 @@ RawItem = Mapping[str, Any]
|
|
|
14
14
|
RawCollection = Iterable[RawItem]
|
|
15
15
|
|
|
16
16
|
|
|
17
|
-
class _RawItemWithId(
|
|
17
|
+
class _RawItemWithId(dict[str, Any]):
|
|
18
18
|
def __post_init__(self) -> None:
|
|
19
19
|
assert "id" in self
|
|
20
20
|
|
|
@@ -22,7 +22,7 @@ class _RawItemWithId(Dict[str, Any]):
|
|
|
22
22
|
RawCollectionWithId = Iterable[_RawItemWithId]
|
|
23
23
|
|
|
24
24
|
|
|
25
|
-
class RestfulService
|
|
25
|
+
class RestfulService: # pragma: no cover
|
|
26
26
|
def create_one(self, item: RawItem) -> RawItem:
|
|
27
27
|
raise NotImplementedError(self.create_one.__name__)
|
|
28
28
|
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import pickle
|
|
4
|
+
from collections.abc import Mapping
|
|
4
5
|
from copy import deepcopy
|
|
5
6
|
from dataclasses import asdict, dataclass, field, fields, is_dataclass
|
|
6
|
-
from typing import Any, Generic,
|
|
7
|
-
|
|
8
|
-
from typing_extensions import get_type_hints
|
|
7
|
+
from typing import Any, Generic, Protocol, Self, TypeVar, get_args, get_type_hints
|
|
9
8
|
|
|
10
9
|
from apexdevkit.fluent import FluentDict
|
|
11
10
|
from apexdevkit.value import Value
|
|
@@ -96,7 +95,7 @@ class DataclassFormatter(Generic[_TargetT]):
|
|
|
96
95
|
key_type = types[key.name]
|
|
97
96
|
if key.name not in raw:
|
|
98
97
|
continue
|
|
99
|
-
|
|
98
|
+
if key.name in self.sub_formatters:
|
|
100
99
|
raw[key.name] = (
|
|
101
100
|
self.sub_formatters[key.name].load(raw.pop(key.name))
|
|
102
101
|
if raw[key.name]
|
|
@@ -2,7 +2,7 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
from dataclasses import dataclass
|
|
4
4
|
from enum import Enum, auto
|
|
5
|
-
from typing import Any, Protocol
|
|
5
|
+
from typing import Any, Protocol
|
|
6
6
|
|
|
7
7
|
from apexdevkit.http.json import JsonDict
|
|
8
8
|
|
|
@@ -103,25 +103,25 @@ class FluentHttpRequest:
|
|
|
103
103
|
class FluentHttpResponse:
|
|
104
104
|
response: HttpResponse
|
|
105
105
|
|
|
106
|
-
def on_bad_request(self, raises: Exception |
|
|
106
|
+
def on_bad_request(self, raises: Exception | type[Exception]) -> FluentHttpResponse:
|
|
107
107
|
if self.response.code() == 400:
|
|
108
108
|
raise raises
|
|
109
109
|
|
|
110
110
|
return self
|
|
111
111
|
|
|
112
|
-
def on_conflict(self, raises: Exception |
|
|
112
|
+
def on_conflict(self, raises: Exception | type[Exception]) -> FluentHttpResponse:
|
|
113
113
|
if self.response.code() == 409:
|
|
114
114
|
raise raises
|
|
115
115
|
|
|
116
116
|
return self
|
|
117
117
|
|
|
118
|
-
def on_not_found(self, raises: Exception |
|
|
118
|
+
def on_not_found(self, raises: Exception | type[Exception]) -> FluentHttpResponse:
|
|
119
119
|
if self.response.code() == 404:
|
|
120
120
|
raise raises
|
|
121
121
|
|
|
122
122
|
return self
|
|
123
123
|
|
|
124
|
-
def on_failure(self, raises:
|
|
124
|
+
def on_failure(self, raises: type[Exception]) -> FluentHttpResponse:
|
|
125
125
|
if self.response.code() < 200 or self.response.code() > 299:
|
|
126
126
|
raise raises(self.response.raw(), self.response.code())
|
|
127
127
|
|
|
@@ -30,7 +30,7 @@ class ApexID:
|
|
|
30
30
|
cls.sequence = 0
|
|
31
31
|
|
|
32
32
|
if cls.sequence > cls._sequence_bitmask:
|
|
33
|
-
raise
|
|
33
|
+
raise DuplicateIDError("Duplicate ID Generated")
|
|
34
34
|
|
|
35
35
|
cls.last_timestamp = current_timestamp
|
|
36
36
|
|
|
@@ -50,5 +50,5 @@ class ApexID:
|
|
|
50
50
|
return int(os.getenv("APEX_ID_METADATA", "0"))
|
|
51
51
|
|
|
52
52
|
|
|
53
|
-
class
|
|
53
|
+
class DuplicateIDError(Exception):
|
|
54
54
|
pass
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
from collections import defaultdict
|
|
4
|
+
from collections.abc import Iterable, Mapping
|
|
4
5
|
from dataclasses import dataclass, field
|
|
5
|
-
from typing import Any, ClassVar, Generic,
|
|
6
|
+
from typing import Any, ClassVar, Generic, Protocol, TypeVar
|
|
6
7
|
|
|
7
8
|
from apexdevkit.annotation import deprecated
|
|
8
9
|
from apexdevkit.error import ForbiddenError
|
|
@@ -59,7 +59,7 @@ class SummaryExtractor:
|
|
|
59
59
|
def _value(self, value: Any) -> NumericValue | DateValue | StringValue | NullValue:
|
|
60
60
|
if value is None:
|
|
61
61
|
return NullValue()
|
|
62
|
-
if isinstance(value,
|
|
62
|
+
if isinstance(value, int | float | Decimal):
|
|
63
63
|
return NumericValue.from_decimal(Decimal(value))
|
|
64
64
|
if self.aggregation.name and (
|
|
65
65
|
"date" in self.aggregation.name.lower()
|
|
@@ -4,7 +4,7 @@ import sqlite3
|
|
|
4
4
|
from contextlib import AbstractContextManager
|
|
5
5
|
from dataclasses import dataclass
|
|
6
6
|
from functools import cached_property
|
|
7
|
-
from typing import Any
|
|
7
|
+
from typing import Any
|
|
8
8
|
|
|
9
9
|
import pymssql
|
|
10
10
|
from pymssql import Connection as _Connection
|
|
@@ -17,7 +17,7 @@ from apexdevkit.repository import Connection
|
|
|
17
17
|
class SqliteFileConnector:
|
|
18
18
|
dsn: str
|
|
19
19
|
|
|
20
|
-
def connect(self) ->
|
|
20
|
+
def connect(self) -> AbstractContextManager[Connection]:
|
|
21
21
|
connection = sqlite3.connect(self.dsn)
|
|
22
22
|
connection.row_factory = sqlite3.Row
|
|
23
23
|
|
|
@@ -28,11 +28,11 @@ class SqliteFileConnector:
|
|
|
28
28
|
class SqliteInMemoryConnector:
|
|
29
29
|
dsn: str = ":memory:"
|
|
30
30
|
|
|
31
|
-
def connect(self) ->
|
|
31
|
+
def connect(self) -> AbstractContextManager[Connection]:
|
|
32
32
|
return self._connection
|
|
33
33
|
|
|
34
34
|
@cached_property
|
|
35
|
-
def _connection(self) ->
|
|
35
|
+
def _connection(self) -> AbstractContextManager[Connection]:
|
|
36
36
|
connection = sqlite3.connect(self.dsn, check_same_thread=False)
|
|
37
37
|
connection.row_factory = sqlite3.Row
|
|
38
38
|
|
|
@@ -48,7 +48,7 @@ class MsSqlConnector:
|
|
|
48
48
|
db_tds_version = "7.0"
|
|
49
49
|
db_port: str | None = None
|
|
50
50
|
|
|
51
|
-
def connect(self) ->
|
|
51
|
+
def connect(self) -> AbstractContextManager[Connection]:
|
|
52
52
|
return ConnectionContextManager(self._connection())
|
|
53
53
|
|
|
54
54
|
def _connection(self) -> Connection:
|
|
@@ -96,16 +96,16 @@ class MsSqlCursorAdapter:
|
|
|
96
96
|
cursor: Cursor
|
|
97
97
|
|
|
98
98
|
def execute(self, *args: Any, **kwargs: Any) -> Any:
|
|
99
|
-
self.cursor.execute(*args, **kwargs)
|
|
99
|
+
self.cursor.execute(*args, **kwargs)
|
|
100
100
|
|
|
101
101
|
def executemany(self, *args: Any, **kwargs: Any) -> Any:
|
|
102
|
-
self.cursor.executemany(*args, **kwargs)
|
|
102
|
+
self.cursor.executemany(*args, **kwargs)
|
|
103
103
|
|
|
104
|
-
def fetchone(self, *
|
|
105
|
-
return self.cursor.fetchone()
|
|
104
|
+
def fetchone(self, *_: Any, **__: Any) -> Any:
|
|
105
|
+
return self.cursor.fetchone()
|
|
106
106
|
|
|
107
|
-
def fetchall(self, *
|
|
108
|
-
return self.cursor.fetchall()
|
|
107
|
+
def fetchall(self, *_: Any, **__: Any) -> Any:
|
|
108
|
+
return self.cursor.fetchall()
|
|
109
109
|
|
|
110
110
|
def close(self) -> None:
|
|
111
111
|
self.cursor.close() # type : ignore
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
from collections.abc import Iterable, Mapping
|
|
4
|
+
from contextlib import AbstractContextManager
|
|
3
5
|
from copy import deepcopy
|
|
4
6
|
from dataclasses import dataclass, field
|
|
5
|
-
from typing import Any,
|
|
7
|
+
from typing import Any, Protocol
|
|
6
8
|
|
|
7
9
|
_RawData = Mapping[str, Any]
|
|
8
10
|
|
|
@@ -45,7 +47,7 @@ class Database:
|
|
|
45
47
|
|
|
46
48
|
|
|
47
49
|
class Connector(Protocol): # pragma: no cover
|
|
48
|
-
def connect(self) ->
|
|
50
|
+
def connect(self) -> AbstractContextManager[Connection]:
|
|
49
51
|
pass
|
|
50
52
|
|
|
51
53
|
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
from collections.abc import Callable, Iterable, Iterator
|
|
3
4
|
from contextlib import suppress
|
|
4
5
|
from dataclasses import dataclass, field
|
|
5
|
-
from typing import Any,
|
|
6
|
+
from typing import Any, Generic, Protocol, Self
|
|
6
7
|
|
|
7
8
|
from apexdevkit.error import DoesNotExistError, ExistsError
|
|
8
9
|
from apexdevkit.formatter import Formatter, PickleFormatter
|
|
@@ -107,7 +108,7 @@ class _SingleKeyRepository(RepositoryBase[ItemT]):
|
|
|
107
108
|
store: KeyValueStore[ItemT]
|
|
108
109
|
pk: _KeyFunction[ItemT]
|
|
109
110
|
|
|
110
|
-
def bind(self, **
|
|
111
|
+
def bind(self, **_: Any) -> Self: # pragma: no cover
|
|
111
112
|
return self
|
|
112
113
|
|
|
113
114
|
def create(self, item: ItemT) -> ItemT:
|
|
@@ -131,14 +132,14 @@ class _SingleKeyRepository(RepositoryBase[ItemT]):
|
|
|
131
132
|
def delete(self, item_id: str) -> None:
|
|
132
133
|
try:
|
|
133
134
|
self.store.drop(item_id)
|
|
134
|
-
except KeyError:
|
|
135
|
-
raise DoesNotExistError(item_id)
|
|
135
|
+
except KeyError as e:
|
|
136
|
+
raise DoesNotExistError(item_id) from e
|
|
136
137
|
|
|
137
138
|
def read(self, item_id: str) -> ItemT:
|
|
138
139
|
try:
|
|
139
140
|
return self.store.get(item_id)
|
|
140
|
-
except KeyError:
|
|
141
|
-
raise DoesNotExistError(item_id)
|
|
141
|
+
except KeyError as e:
|
|
142
|
+
raise DoesNotExistError(item_id) from e
|
|
142
143
|
|
|
143
144
|
def __iter__(self) -> Iterator[ItemT]:
|
|
144
145
|
return iter(self.store.values())
|
|
@@ -153,7 +154,7 @@ class _ManyKeyRepository(RepositoryBase[ItemT]):
|
|
|
153
154
|
|
|
154
155
|
keys: list[_KeyFunction[ItemT]] = field(default_factory=list)
|
|
155
156
|
|
|
156
|
-
def bind(self, **
|
|
157
|
+
def bind(self, **_: Any) -> Self: # pragma: no cover
|
|
157
158
|
return self
|
|
158
159
|
|
|
159
160
|
def create(self, item: ItemT) -> ItemT:
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
from collections.abc import Iterable, Iterator, Mapping
|
|
3
4
|
from dataclasses import dataclass
|
|
4
|
-
from typing import Any, Generic,
|
|
5
|
+
from typing import Any, Generic, TypeVar
|
|
5
6
|
|
|
6
7
|
from pymssql.exceptions import DatabaseError, OperationalError
|
|
7
8
|
|
|
@@ -27,8 +28,8 @@ class MsSqlRepository(RepositoryBase[ItemT]):
|
|
|
27
28
|
|
|
28
29
|
try:
|
|
29
30
|
return int(raw["n_items"])
|
|
30
|
-
except KeyError:
|
|
31
|
-
raise UnknownError(raw)
|
|
31
|
+
except KeyError as e:
|
|
32
|
+
raise UnknownError(raw) from e
|
|
32
33
|
|
|
33
34
|
def delete(self, item_id: str) -> None:
|
|
34
35
|
self.db.execute(self.table.delete(item_id)).fetch_none()
|
|
@@ -40,21 +41,18 @@ class MsSqlRepository(RepositoryBase[ItemT]):
|
|
|
40
41
|
try:
|
|
41
42
|
return self.table.load(self.db.execute(self.table.insert(item)).fetch_one())
|
|
42
43
|
except DatabaseError as e:
|
|
43
|
-
|
|
44
|
+
if MssqlException(e).is_duplication():
|
|
45
|
+
raise self.table.exists(item) from e
|
|
44
46
|
|
|
45
|
-
|
|
46
|
-
raise self.table.exists(item)
|
|
47
|
-
|
|
48
|
-
raise UnknownError(e.message)
|
|
47
|
+
raise UnknownError(MssqlException(e).message) from e
|
|
49
48
|
|
|
50
49
|
def read(self, item_id: str) -> ItemT:
|
|
51
50
|
try:
|
|
52
51
|
raw = self.db.execute(self.table.select(item_id)).fetch_one()
|
|
53
52
|
except OperationalError as e:
|
|
54
53
|
if "Conversion failed" in str(e):
|
|
55
|
-
raise DoesNotExistError(item_id)
|
|
56
|
-
|
|
57
|
-
raise e
|
|
54
|
+
raise DoesNotExistError(item_id) from e
|
|
55
|
+
raise e
|
|
58
56
|
|
|
59
57
|
if not raw:
|
|
60
58
|
raise DoesNotExistError(item_id)
|
|
@@ -273,7 +271,7 @@ class DefaultSqlTable(SqlTable[ItemT]):
|
|
|
273
271
|
[f"%({key.name})s" for key in self.fields if key.include_in_insert]
|
|
274
272
|
)
|
|
275
273
|
try:
|
|
276
|
-
self.fields.id
|
|
274
|
+
_ = self.fields.id
|
|
277
275
|
output = ", ".join(
|
|
278
276
|
["[" + field.name + "] AS " + field.name for field in self.fields]
|
|
279
277
|
)
|
|
@@ -368,12 +366,11 @@ class DefaultSqlTable(SqlTable[ItemT]):
|
|
|
368
366
|
def exists(self, duplicate: ItemT) -> ExistsError:
|
|
369
367
|
raw = self.formatter.dump(duplicate)
|
|
370
368
|
return ExistsError(duplicate).with_duplicate(
|
|
371
|
-
lambda
|
|
369
|
+
lambda _: f"{self.fields.id}<{raw[self.fields.id]}>"
|
|
372
370
|
)
|
|
373
371
|
|
|
374
372
|
@property
|
|
375
373
|
def _user_check(self) -> str:
|
|
376
374
|
if self.username is not None:
|
|
377
375
|
return f"EXECUTE AS USER = '{self.username}'"
|
|
378
|
-
|
|
379
|
-
return ""
|
|
376
|
+
return ""
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
from collections.abc import Callable, Iterator
|
|
3
4
|
from dataclasses import dataclass, field
|
|
4
|
-
from typing import
|
|
5
|
+
from typing import Generic, TypeVar
|
|
5
6
|
|
|
6
7
|
from apexdevkit.error import DoesNotExistError
|
|
7
8
|
from apexdevkit.formatter import Formatter
|
|
@@ -74,23 +75,35 @@ class MultipleRepositoryBuilder(Generic[ItemT]):
|
|
|
74
75
|
def with_repository(
|
|
75
76
|
self,
|
|
76
77
|
repository: Repository[ItemT],
|
|
77
|
-
condition: Callable[[ItemT], bool] = lambda
|
|
78
|
-
formatter: Formatter[ItemT, ItemT] =
|
|
78
|
+
condition: Callable[[ItemT], bool] = lambda _: True,
|
|
79
|
+
formatter: Formatter[ItemT, ItemT] | None = None,
|
|
79
80
|
id_prefix: str = "",
|
|
80
81
|
) -> MultipleRepositoryBuilder[ItemT]:
|
|
81
82
|
return MultipleRepositoryBuilder[ItemT](
|
|
82
83
|
self.repositories
|
|
83
|
-
+ [
|
|
84
|
+
+ [
|
|
85
|
+
_InnerRepository(
|
|
86
|
+
repository,
|
|
87
|
+
condition,
|
|
88
|
+
formatter or NoFormatter[ItemT](),
|
|
89
|
+
id_prefix,
|
|
90
|
+
)
|
|
91
|
+
]
|
|
84
92
|
)
|
|
85
93
|
|
|
86
94
|
def and_repository(
|
|
87
95
|
self,
|
|
88
96
|
repository: Repository[ItemT],
|
|
89
|
-
condition: Callable[[ItemT], bool] = lambda
|
|
90
|
-
formatter: Formatter[ItemT, ItemT] =
|
|
97
|
+
condition: Callable[[ItemT], bool] = lambda _: True,
|
|
98
|
+
formatter: Formatter[ItemT, ItemT] | None = None,
|
|
91
99
|
id_prefix: str = "",
|
|
92
100
|
) -> MultipleRepositoryBuilder[ItemT]:
|
|
93
|
-
return self.with_repository(
|
|
101
|
+
return self.with_repository(
|
|
102
|
+
repository,
|
|
103
|
+
condition,
|
|
104
|
+
formatter or NoFormatter[ItemT](),
|
|
105
|
+
id_prefix,
|
|
106
|
+
)
|
|
94
107
|
|
|
95
108
|
def build(self) -> MultipleRepository[ItemT]:
|
|
96
109
|
return MultipleRepository[ItemT](self.repositories)
|
|
@@ -99,7 +112,7 @@ class MultipleRepositoryBuilder(Generic[ItemT]):
|
|
|
99
112
|
@dataclass(frozen=True)
|
|
100
113
|
class _InnerRepository(Generic[ItemT]):
|
|
101
114
|
inner: Repository[ItemT]
|
|
102
|
-
condition: Callable[[ItemT], bool] = lambda
|
|
115
|
+
condition: Callable[[ItemT], bool] = lambda _: True
|
|
103
116
|
formatter: Formatter[ItemT, ItemT] = field(
|
|
104
117
|
default_factory=lambda: NoFormatter[ItemT]()
|
|
105
118
|
)
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
from collections.abc import Iterator, Mapping
|
|
3
4
|
from dataclasses import dataclass, field
|
|
4
|
-
from typing import Any
|
|
5
|
+
from typing import Any
|
|
5
6
|
|
|
6
7
|
|
|
7
8
|
@dataclass(frozen=True)
|
|
@@ -144,8 +145,8 @@ class SqlFieldManager:
|
|
|
144
145
|
]
|
|
145
146
|
if len(ordering) > 0:
|
|
146
147
|
return "ORDER BY " + ", ".join(order_clauses)
|
|
147
|
-
|
|
148
|
-
|
|
148
|
+
|
|
149
|
+
return ""
|
|
149
150
|
|
|
150
151
|
def __iter__(self) -> Iterator[_SqlField]:
|
|
151
152
|
yield from self.fields
|
|
@@ -162,8 +163,8 @@ class SqlFieldManager:
|
|
|
162
163
|
]
|
|
163
164
|
if len(statements) > 0:
|
|
164
165
|
return "WHERE " + " AND ".join(statements)
|
|
165
|
-
|
|
166
|
-
|
|
166
|
+
|
|
167
|
+
return ""
|
|
167
168
|
|
|
168
169
|
def with_fixed(self, raw: Mapping[str, Any]) -> dict[str, Any]:
|
|
169
170
|
data = dict(raw)
|
|
@@ -184,14 +185,13 @@ class SqlFieldManager:
|
|
|
184
185
|
if result is not None:
|
|
185
186
|
if result.parent_value is None:
|
|
186
187
|
return self.key_formatter.replace("x", result.name) + " IS NULL"
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
return ""
|
|
188
|
+
return (
|
|
189
|
+
self.key_formatter.replace("x", result.name)
|
|
190
|
+
+ " = "
|
|
191
|
+
+ self.value_formatter.replace("x", result.name)
|
|
192
|
+
)
|
|
193
|
+
|
|
194
|
+
return ""
|
|
195
195
|
|
|
196
196
|
def _id_filter(self, include_id: bool, read_id: bool) -> str:
|
|
197
197
|
return (
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
from collections.abc import Iterable, Iterator, Mapping
|
|
3
4
|
from dataclasses import dataclass
|
|
4
5
|
from sqlite3 import IntegrityError
|
|
5
|
-
from typing import Any, Generic
|
|
6
|
+
from typing import Any, Generic
|
|
6
7
|
|
|
7
8
|
from apexdevkit.error import DoesNotExistError, ExistsError
|
|
8
9
|
from apexdevkit.formatter import Formatter
|
|
@@ -28,8 +29,8 @@ class SqliteRepository(RepositoryBase[ItemT]):
|
|
|
28
29
|
|
|
29
30
|
try:
|
|
30
31
|
return int(raw["n_items"])
|
|
31
|
-
except KeyError:
|
|
32
|
-
raise UnknownError(raw)
|
|
32
|
+
except KeyError as e:
|
|
33
|
+
raise UnknownError(raw) from e
|
|
33
34
|
|
|
34
35
|
def create(self, item: ItemT) -> ItemT:
|
|
35
36
|
try:
|
|
@@ -60,7 +61,7 @@ class SqliteRepository(RepositoryBase[ItemT]):
|
|
|
60
61
|
|
|
61
62
|
|
|
62
63
|
class SqlTable(Generic[ItemT]): # pragma: no cover
|
|
63
|
-
def bind(self, **
|
|
64
|
+
def bind(self, **_: Any) -> SqlTable[ItemT]:
|
|
64
65
|
return self
|
|
65
66
|
|
|
66
67
|
def count_all(self) -> DatabaseCommand:
|
|
@@ -91,7 +92,7 @@ class SqlTable(Generic[ItemT]): # pragma: no cover
|
|
|
91
92
|
raise NotImplementedError
|
|
92
93
|
|
|
93
94
|
def duplicate(self, item: ItemT) -> ExistsError:
|
|
94
|
-
return ExistsError(item).with_duplicate(lambda
|
|
95
|
+
return ExistsError(item).with_duplicate(lambda _: "Unknown")
|
|
95
96
|
|
|
96
97
|
|
|
97
98
|
@dataclass
|
|
@@ -183,7 +184,7 @@ class _DefaultSqlTable(SqlTable[ItemT]):
|
|
|
183
184
|
|
|
184
185
|
return DatabaseCommand(f"""
|
|
185
186
|
SELECT
|
|
186
|
-
{columns}
|
|
187
|
+
{columns}
|
|
187
188
|
FROM {self.table_name.upper()}
|
|
188
189
|
{self.fields.where_statement(include_id=True)};
|
|
189
190
|
""").with_data(self.fields.with_fixed({self.fields.id: item_id}))
|
|
@@ -198,7 +199,7 @@ class _DefaultSqlTable(SqlTable[ItemT]):
|
|
|
198
199
|
|
|
199
200
|
return DatabaseCommand(f"""
|
|
200
201
|
SELECT
|
|
201
|
-
{columns}
|
|
202
|
+
{columns}
|
|
202
203
|
FROM {self.table_name.upper()}
|
|
203
204
|
WHERE {duplicates};
|
|
204
205
|
""").with_data({key: raw[key] for key in raw if key in self.fields.composite})
|
|
@@ -250,7 +251,7 @@ class _DefaultSqlTable(SqlTable[ItemT]):
|
|
|
250
251
|
def duplicate(self, item: ItemT) -> ExistsError:
|
|
251
252
|
raw = self.formatter.dump(item)
|
|
252
253
|
return ExistsError(item).with_duplicate(
|
|
253
|
-
lambda
|
|
254
|
+
lambda _: ",".join(
|
|
254
255
|
[f"{key}<{raw[key]}>" for key in raw if key in self.fields.composite]
|
|
255
256
|
)
|
|
256
257
|
)
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
from collections.abc import Iterable, Iterator
|
|
3
4
|
from dataclasses import dataclass
|
|
4
|
-
from typing import Generic,
|
|
5
|
+
from typing import Generic, Protocol, TypeVar
|
|
5
6
|
|
|
6
7
|
ItemT = TypeVar("ItemT")
|
|
7
8
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from contextlib import nullcontext
|
|
3
|
+
from contextlib import AbstractContextManager, nullcontext
|
|
4
4
|
from dataclasses import dataclass, field
|
|
5
|
-
from typing import Any,
|
|
5
|
+
from typing import Any, Self
|
|
6
6
|
|
|
7
7
|
from apexdevkit.repository import DatabaseCommand
|
|
8
8
|
|
|
@@ -27,7 +27,7 @@ class FakeConnector:
|
|
|
27
27
|
def fetchall(self) -> list[dict[str, Any]]:
|
|
28
28
|
return self.results.pop() # type: ignore
|
|
29
29
|
|
|
30
|
-
def connect(self) ->
|
|
30
|
+
def connect(self) -> AbstractContextManager[Self]:
|
|
31
31
|
return nullcontext(self)
|
|
32
32
|
|
|
33
33
|
def cursor(self) -> Self:
|
|
@@ -3,7 +3,7 @@ from __future__ import annotations
|
|
|
3
3
|
import random
|
|
4
4
|
from dataclasses import dataclass, field
|
|
5
5
|
from functools import cached_property
|
|
6
|
-
from typing import Any, Generic,
|
|
6
|
+
from typing import Any, Generic, TypeVar
|
|
7
7
|
|
|
8
8
|
from faker import Faker
|
|
9
9
|
|
|
@@ -70,7 +70,7 @@ class Fake:
|
|
|
70
70
|
|
|
71
71
|
@dataclass(frozen=True)
|
|
72
72
|
class FakeResource(Generic[ItemT]):
|
|
73
|
-
item_type:
|
|
73
|
+
item_type: type[ItemT] = field()
|
|
74
74
|
fake: Fake = field(default_factory=Fake)
|
|
75
75
|
|
|
76
76
|
@cached_property
|
|
@@ -89,7 +89,7 @@ class FakeResource(Generic[ItemT]):
|
|
|
89
89
|
|
|
90
90
|
@dataclass(frozen=True)
|
|
91
91
|
class FakeValue(FakeResource[Value]):
|
|
92
|
-
item_type:
|
|
92
|
+
item_type: type[Value] = field(default=Value)
|
|
93
93
|
|
|
94
94
|
@cached_property
|
|
95
95
|
def _raw(self) -> dict[str, Any]:
|
|
@@ -101,7 +101,7 @@ class FakeValue(FakeResource[Value]):
|
|
|
101
101
|
|
|
102
102
|
@dataclass(frozen=True)
|
|
103
103
|
class FakeNumericValue(FakeResource[NumericValue]):
|
|
104
|
-
item_type:
|
|
104
|
+
item_type: type[NumericValue] = field(default=NumericValue)
|
|
105
105
|
|
|
106
106
|
@cached_property
|
|
107
107
|
def _raw(self) -> dict[str, Any]:
|
|
@@ -113,7 +113,7 @@ class FakeNumericValue(FakeResource[NumericValue]):
|
|
|
113
113
|
|
|
114
114
|
@dataclass(frozen=True)
|
|
115
115
|
class FakeStringValue(FakeResource[StringValue]):
|
|
116
|
-
item_type:
|
|
116
|
+
item_type: type[StringValue] = field(default=StringValue)
|
|
117
117
|
|
|
118
118
|
@cached_property
|
|
119
119
|
def _raw(self) -> dict[str, Any]:
|
|
@@ -124,7 +124,7 @@ class FakeStringValue(FakeResource[StringValue]):
|
|
|
124
124
|
|
|
125
125
|
@dataclass(frozen=True)
|
|
126
126
|
class FakeDateValue(FakeResource[DateValue]):
|
|
127
|
-
item_type:
|
|
127
|
+
item_type: type[DateValue] = field(default=DateValue)
|
|
128
128
|
|
|
129
129
|
@cached_property
|
|
130
130
|
def _raw(self) -> dict[str, Any]:
|
|
@@ -134,7 +134,7 @@ class FakeDateValue(FakeResource[DateValue]):
|
|
|
134
134
|
@dataclass(frozen=True)
|
|
135
135
|
class FakeLeaf(FakeResource[Leaf]):
|
|
136
136
|
values: list[NumericValue | StringValue | DateValue] = field(default_factory=list)
|
|
137
|
-
item_type:
|
|
137
|
+
item_type: type[Leaf] = field(default=Leaf)
|
|
138
138
|
|
|
139
139
|
@cached_property
|
|
140
140
|
def _raw(self) -> dict[str, Any]:
|
|
@@ -147,7 +147,7 @@ class FakeLeaf(FakeResource[Leaf]):
|
|
|
147
147
|
@dataclass(frozen=True)
|
|
148
148
|
class FakeOperator(FakeResource[Operator]):
|
|
149
149
|
operands: list[Operator | Leaf] = field(default_factory=list)
|
|
150
|
-
item_type:
|
|
150
|
+
item_type: type[Operator] = field(default=Operator)
|
|
151
151
|
|
|
152
152
|
@cached_property
|
|
153
153
|
def _raw(self) -> dict[str, Any]:
|
|
@@ -160,7 +160,7 @@ class FakeOperator(FakeResource[Operator]):
|
|
|
160
160
|
@dataclass(frozen=True)
|
|
161
161
|
class FakeSort(FakeResource[Sort]):
|
|
162
162
|
is_descending: bool | None = None
|
|
163
|
-
item_type:
|
|
163
|
+
item_type: type[Sort] = field(default=Sort)
|
|
164
164
|
|
|
165
165
|
@cached_property
|
|
166
166
|
def _raw(self) -> dict[str, Any]:
|
|
@@ -174,7 +174,7 @@ class FakeSort(FakeResource[Sort]):
|
|
|
174
174
|
|
|
175
175
|
@dataclass(frozen=True)
|
|
176
176
|
class FakePage(FakeResource[Page]):
|
|
177
|
-
item_type:
|
|
177
|
+
item_type: type[Page] = field(default=Page)
|
|
178
178
|
|
|
179
179
|
@cached_property
|
|
180
180
|
def _raw(self) -> dict[str, Any]:
|
|
@@ -188,7 +188,7 @@ class FakePage(FakeResource[Page]):
|
|
|
188
188
|
@dataclass(frozen=True)
|
|
189
189
|
class FakeFilter(FakeResource[Filter]):
|
|
190
190
|
args: list[NumericValue | StringValue] = field(default_factory=list)
|
|
191
|
-
item_type:
|
|
191
|
+
item_type: type[Filter] = field(default=Filter)
|
|
192
192
|
|
|
193
193
|
@cached_property
|
|
194
194
|
def _raw(self) -> dict[str, Any]:
|
|
@@ -203,7 +203,7 @@ class FakeQueryOptions(FakeResource[QueryOptions]):
|
|
|
203
203
|
condition: Operator | None = None
|
|
204
204
|
ordering: list[Sort] = field(default_factory=list)
|
|
205
205
|
paging: Page | None = None
|
|
206
|
-
item_type:
|
|
206
|
+
item_type: type[QueryOptions] = field(default=QueryOptions)
|
|
207
207
|
|
|
208
208
|
@cached_property
|
|
209
209
|
def _raw(self) -> dict[str, Any]:
|
|
@@ -217,7 +217,7 @@ class FakeQueryOptions(FakeResource[QueryOptions]):
|
|
|
217
217
|
|
|
218
218
|
@dataclass(frozen=True)
|
|
219
219
|
class FakeAggregationOption(FakeResource[AggregationOption]):
|
|
220
|
-
item_type:
|
|
220
|
+
item_type: type[AggregationOption] = field(default=AggregationOption)
|
|
221
221
|
|
|
222
222
|
@cached_property
|
|
223
223
|
def _raw(self) -> dict[str, Any]:
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
from collections.abc import Iterable
|
|
3
4
|
from dataclasses import dataclass
|
|
4
5
|
from functools import cached_property
|
|
5
|
-
from typing import Any,
|
|
6
|
+
from typing import Any, Self
|
|
6
7
|
|
|
7
8
|
from apexdevkit.fastapi.name import RestfulName
|
|
8
9
|
from apexdevkit.fastapi.request import HttpRequest
|
|
@@ -1,16 +1,19 @@
|
|
|
1
|
-
[
|
|
1
|
+
[project]
|
|
2
2
|
name = "apexdevkit"
|
|
3
|
-
version = "1.
|
|
3
|
+
version = "1.23.2"
|
|
4
4
|
description = "Apex Development Tools for python."
|
|
5
|
-
authors = ["Apex Dev <dev@apex.ge>"]
|
|
6
5
|
readme = "README.md"
|
|
6
|
+
authors = [
|
|
7
|
+
{ name = "Apex Dev", email = "dev@apex.ge" }
|
|
8
|
+
]
|
|
9
|
+
dynamic = ["dependencies"]
|
|
10
|
+
requires-python = ">=3.11"
|
|
7
11
|
|
|
8
12
|
[tool.poetry.dependencies]
|
|
9
|
-
python = "^3.11"
|
|
10
13
|
httpx = "*"
|
|
11
14
|
fastapi = "*"
|
|
12
15
|
uvicorn = "*"
|
|
13
|
-
sentry-sdk = {extras = ["fastapi"], version = "*"}
|
|
16
|
+
sentry-sdk = { extras = ["fastapi"], version = "*" }
|
|
14
17
|
python-dotenv = "*"
|
|
15
18
|
pymssql = "2.3.2"
|
|
16
19
|
|
|
@@ -22,14 +25,12 @@ pytest-cov = "*"
|
|
|
22
25
|
pytest-recording = "*"
|
|
23
26
|
coverage = "*"
|
|
24
27
|
faker = "*"
|
|
25
|
-
mongomock = "*"
|
|
26
28
|
|
|
27
29
|
[tool.poetry.group.lint.dependencies]
|
|
28
30
|
mypy = "*"
|
|
29
31
|
ruff = "*"
|
|
30
32
|
|
|
31
33
|
[tool.mypy]
|
|
32
|
-
python_version = "3.11"
|
|
33
34
|
ignore_missing_imports = true
|
|
34
35
|
strict = true
|
|
35
36
|
exclude = [
|
|
@@ -38,7 +39,6 @@ exclude = [
|
|
|
38
39
|
]
|
|
39
40
|
|
|
40
41
|
[tool.ruff]
|
|
41
|
-
target-version = "py311"
|
|
42
42
|
line-length = 88
|
|
43
43
|
|
|
44
44
|
exclude = [
|
|
@@ -48,10 +48,29 @@ exclude = [
|
|
|
48
48
|
"venv",
|
|
49
49
|
]
|
|
50
50
|
|
|
51
|
-
lint
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
51
|
+
[tool.ruff.lint]
|
|
52
|
+
select = [
|
|
53
|
+
"A", # flake8-builtins
|
|
54
|
+
"ARG", # flake8-unused-arguments
|
|
55
|
+
"B", # flake8-bugbear
|
|
56
|
+
"C4", # flake8-comprehensions
|
|
57
|
+
"PT", # flake8-pytest-style
|
|
58
|
+
"RSE", # flake8-raise
|
|
59
|
+
"RET", # flake8-return
|
|
60
|
+
"SIM", # flake8-simplify
|
|
61
|
+
"T20", # flake8-print
|
|
62
|
+
"E", # pycodestyle errors
|
|
63
|
+
"W", # pycodestyle warnings
|
|
64
|
+
"F", # pyflakes
|
|
65
|
+
"I", # isort
|
|
66
|
+
"N", # pep8-naming
|
|
67
|
+
"UP", # pyupgrade
|
|
68
|
+
]
|
|
69
|
+
|
|
70
|
+
[tool.ruff.lint.per-file-ignores]
|
|
71
|
+
"apexdevkit/fastapi/resource.py" = ["N803"]
|
|
72
|
+
"apexdevkit/fastapi/dependable.py" = ["N806"]
|
|
73
|
+
|
|
55
74
|
|
|
56
75
|
[tool.ruff.lint.mccabe]
|
|
57
76
|
max-complexity = 10
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|