apexdevkit 1.22.2__tar.gz → 1.23.1__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.
Files changed (54) hide show
  1. {apexdevkit-1.22.2 → apexdevkit-1.23.1}/PKG-INFO +2 -2
  2. {apexdevkit-1.22.2 → apexdevkit-1.23.1}/apexdevkit/annotation/deprecate.py +2 -1
  3. {apexdevkit-1.22.2 → apexdevkit-1.23.1}/apexdevkit/error.py +2 -1
  4. {apexdevkit-1.22.2 → apexdevkit-1.23.1}/apexdevkit/fastapi/builder.py +2 -1
  5. {apexdevkit-1.22.2 → apexdevkit-1.23.1}/apexdevkit/fastapi/dependable.py +3 -2
  6. {apexdevkit-1.22.2 → apexdevkit-1.23.1}/apexdevkit/fastapi/resource.py +2 -1
  7. {apexdevkit-1.22.2 → apexdevkit-1.23.1}/apexdevkit/fastapi/response.py +2 -1
  8. {apexdevkit-1.22.2 → apexdevkit-1.23.1}/apexdevkit/fastapi/schema.py +6 -5
  9. {apexdevkit-1.22.2 → apexdevkit-1.23.1}/apexdevkit/fastapi/service.py +4 -4
  10. {apexdevkit-1.22.2 → apexdevkit-1.23.1}/apexdevkit/fluent.py +2 -1
  11. {apexdevkit-1.22.2 → apexdevkit-1.23.1}/apexdevkit/formatter.py +2 -3
  12. {apexdevkit-1.22.2 → apexdevkit-1.23.1}/apexdevkit/http/fluent.py +5 -5
  13. {apexdevkit-1.22.2 → apexdevkit-1.23.1}/apexdevkit/http/httpx/client.py +2 -1
  14. {apexdevkit-1.22.2 → apexdevkit-1.23.1}/apexdevkit/query/generator.py +2 -1
  15. {apexdevkit-1.22.2 → apexdevkit-1.23.1}/apexdevkit/query/query.py +1 -1
  16. {apexdevkit-1.22.2 → apexdevkit-1.23.1}/apexdevkit/repository/base.py +2 -1
  17. {apexdevkit-1.22.2 → apexdevkit-1.23.1}/apexdevkit/repository/connector.py +5 -5
  18. {apexdevkit-1.22.2 → apexdevkit-1.23.1}/apexdevkit/repository/database.py +4 -2
  19. {apexdevkit-1.22.2 → apexdevkit-1.23.1}/apexdevkit/repository/decorator.py +2 -1
  20. {apexdevkit-1.22.2 → apexdevkit-1.23.1}/apexdevkit/repository/in_memory.py +6 -5
  21. {apexdevkit-1.22.2 → apexdevkit-1.23.1}/apexdevkit/repository/interface.py +2 -2
  22. {apexdevkit-1.22.2 → apexdevkit-1.23.1}/apexdevkit/repository/mssql.py +9 -10
  23. {apexdevkit-1.22.2 → apexdevkit-1.23.1}/apexdevkit/repository/repository.py +18 -5
  24. {apexdevkit-1.22.2 → apexdevkit-1.23.1}/apexdevkit/repository/sql.py +2 -1
  25. {apexdevkit-1.22.2 → apexdevkit-1.23.1}/apexdevkit/repository/sqlite.py +6 -5
  26. {apexdevkit-1.22.2 → apexdevkit-1.23.1}/apexdevkit/server.py +2 -1
  27. {apexdevkit-1.22.2 → apexdevkit-1.23.1}/apexdevkit/synchronization.py +2 -1
  28. {apexdevkit-1.22.2 → apexdevkit-1.23.1}/apexdevkit/testing/database.py +3 -3
  29. {apexdevkit-1.22.2 → apexdevkit-1.23.1}/apexdevkit/testing/fake.py +13 -13
  30. {apexdevkit-1.22.2 → apexdevkit-1.23.1}/apexdevkit/testing/rest.py +2 -1
  31. {apexdevkit-1.22.2 → apexdevkit-1.23.1}/pyproject.toml +18 -12
  32. {apexdevkit-1.22.2 → apexdevkit-1.23.1}/LICENSE +0 -0
  33. {apexdevkit-1.22.2 → apexdevkit-1.23.1}/README.md +0 -0
  34. {apexdevkit-1.22.2 → apexdevkit-1.23.1}/apexdevkit/__init__.py +0 -0
  35. {apexdevkit-1.22.2 → apexdevkit-1.23.1}/apexdevkit/annotation/__init__.py +0 -0
  36. {apexdevkit-1.22.2 → apexdevkit-1.23.1}/apexdevkit/environment.py +0 -0
  37. {apexdevkit-1.22.2 → apexdevkit-1.23.1}/apexdevkit/fastapi/__init__.py +0 -0
  38. {apexdevkit-1.22.2 → apexdevkit-1.23.1}/apexdevkit/fastapi/docs.py +0 -0
  39. {apexdevkit-1.22.2 → apexdevkit-1.23.1}/apexdevkit/fastapi/name.py +0 -0
  40. {apexdevkit-1.22.2 → apexdevkit-1.23.1}/apexdevkit/fastapi/request.py +0 -0
  41. {apexdevkit-1.22.2 → apexdevkit-1.23.1}/apexdevkit/fastapi/router.py +0 -0
  42. {apexdevkit-1.22.2 → apexdevkit-1.23.1}/apexdevkit/http/__init__.py +0 -0
  43. {apexdevkit-1.22.2 → apexdevkit-1.23.1}/apexdevkit/http/fake.py +0 -0
  44. {apexdevkit-1.22.2 → apexdevkit-1.23.1}/apexdevkit/http/httpx/__init__.py +0 -0
  45. {apexdevkit-1.22.2 → apexdevkit-1.23.1}/apexdevkit/http/httpx/hooks.py +0 -0
  46. {apexdevkit-1.22.2 → apexdevkit-1.23.1}/apexdevkit/http/json.py +0 -0
  47. {apexdevkit-1.22.2 → apexdevkit-1.23.1}/apexdevkit/http/url.py +0 -0
  48. {apexdevkit-1.22.2 → apexdevkit-1.23.1}/apexdevkit/id.py +0 -0
  49. {apexdevkit-1.22.2 → apexdevkit-1.23.1}/apexdevkit/key_fn.py +0 -0
  50. {apexdevkit-1.22.2 → apexdevkit-1.23.1}/apexdevkit/py.typed +0 -0
  51. {apexdevkit-1.22.2 → apexdevkit-1.23.1}/apexdevkit/query/__init__.py +0 -0
  52. {apexdevkit-1.22.2 → apexdevkit-1.23.1}/apexdevkit/repository/__init__.py +0 -0
  53. {apexdevkit-1.22.2 → apexdevkit-1.23.1}/apexdevkit/testing/__init__.py +0 -0
  54. {apexdevkit-1.22.2 → apexdevkit-1.23.1}/apexdevkit/value.py +0 -0
@@ -1,10 +1,10 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: apexdevkit
3
- Version: 1.22.2
3
+ Version: 1.23.1
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,<4.0
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 typing import Any, Callable, TypeVar, cast
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])
@@ -1,7 +1,8 @@
1
1
  from __future__ import annotations
2
2
 
3
+ from collections.abc import Callable
3
4
  from dataclasses import dataclass, field
4
- from typing import Any, Callable, Self
5
+ from typing import Any, Self
5
6
 
6
7
  Criteria = Callable[[Any], str]
7
8
 
@@ -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, Mapping, Self
6
+ from typing import Any, Self
6
7
 
7
8
  from fastapi import APIRouter, FastAPI
8
9
  from starlette.middleware.cors import CORSMiddleware
@@ -1,5 +1,6 @@
1
+ from collections.abc import Callable
1
2
  from dataclasses import dataclass
2
- from typing import Annotated, Any, Callable, Protocol
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,6 +1,7 @@
1
1
  import re
2
+ from collections.abc import Callable
2
3
  from dataclasses import dataclass
3
- from typing import Any, Callable, Union
4
+ from typing import Any, Union
4
5
 
5
6
  from pydantic import BaseModel
6
7
  from starlette.responses import JSONResponse
@@ -1,5 +1,6 @@
1
+ from collections.abc import Iterable
1
2
  from dataclasses import dataclass
2
- from typing import Any, Iterable
3
+ from typing import Any
3
4
 
4
5
  from apexdevkit.error import DoesNotExistError, ExistsError, ForbiddenError
5
6
  from apexdevkit.fastapi.name import RestfulName
@@ -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, Callable, Iterable, List
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: List[schema], "count": int})
43
- self._schema_for("CreateMany", {self.name.plural: List[create_schema]})
44
- self._schema_for("UpdateMany", {self.name.plural: List[update_many_item]})
45
- self._schema_for("ReplaceMany", {self.name.plural: List[replace_schema]})
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 ABC
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, Dict, Generic, Iterable, Mapping, TypeVar
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(Dict[str, Any]):
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(ABC): # pragma: no cover
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,7 +1,8 @@
1
1
  from __future__ import annotations
2
2
 
3
+ from collections.abc import Callable
3
4
  from dataclasses import dataclass
4
- from typing import Any, Callable, Generic, TypeVar
5
+ from typing import Any, Generic, TypeVar
5
6
 
6
7
  ItemT = TypeVar("ItemT")
7
8
 
@@ -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, Mapping, Protocol, Self, TypeVar, get_args
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
@@ -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, Type
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 | Type[Exception]) -> FluentHttpResponse:
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 | Type[Exception]) -> FluentHttpResponse:
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 | Type[Exception]) -> FluentHttpResponse:
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: Type[Exception]) -> FluentHttpResponse:
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
 
@@ -1,7 +1,8 @@
1
1
  from __future__ import annotations
2
2
 
3
+ from collections.abc import Callable, Iterator, Mapping
3
4
  from dataclasses import dataclass, field
4
- from typing import Any, Callable, Iterator, Mapping
5
+ from typing import Any
5
6
 
6
7
  import httpx
7
8
 
@@ -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, Iterable, Mapping, Protocol, TypeVar
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, (int, float, Decimal)):
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()
@@ -1,4 +1,5 @@
1
- from typing import Any, Generic, Iterator
1
+ from collections.abc import Iterator
2
+ from typing import Any, Generic
2
3
 
3
4
  from apexdevkit.repository.interface import ItemT, Repository
4
5
 
@@ -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, ContextManager
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) -> ContextManager[Connection]:
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) -> ContextManager[Connection]:
31
+ def connect(self) -> AbstractContextManager[Connection]:
32
32
  return self._connection
33
33
 
34
34
  @cached_property
35
- def _connection(self) -> ContextManager[Connection]:
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) -> ContextManager[Connection]:
51
+ def connect(self) -> AbstractContextManager[Connection]:
52
52
  return ConnectionContextManager(self._connection())
53
53
 
54
54
  def _connection(self) -> Connection:
@@ -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, ContextManager, Iterable, Mapping, Protocol
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) -> ContextManager[Connection]:
50
+ def connect(self) -> AbstractContextManager[Connection]:
49
51
  pass
50
52
 
51
53
 
@@ -1,5 +1,6 @@
1
+ from collections.abc import Iterable, Iterator
1
2
  from dataclasses import dataclass
2
- from typing import Any, Generic, Iterable, Iterator
3
+ from typing import Any, Generic
3
4
 
4
5
  from apexdevkit.repository.interface import ItemT, Repository
5
6
 
@@ -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, Callable, Generic, Iterable, Iterator, Protocol, Self
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
@@ -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())
@@ -1,7 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
- from collections.abc import Iterable
4
- from typing import Any, Iterator, Protocol, TypeVar
3
+ from collections.abc import Iterable, Iterator
4
+ from typing import Any, Protocol, TypeVar
5
5
 
6
6
  ItemT = TypeVar("ItemT")
7
7
 
@@ -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, Iterable, Iterator, Mapping, TypeVar
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,19 +41,17 @@ 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
- e = MssqlException(e)
44
+ if MssqlException(e).is_duplication():
45
+ raise self.table.exists(item) from e
44
46
 
45
- if e.is_duplication():
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)
54
+ raise DoesNotExistError(item_id) from e
56
55
  else:
57
56
  raise e
58
57
 
@@ -273,7 +272,7 @@ class DefaultSqlTable(SqlTable[ItemT]):
273
272
  [f"%({key.name})s" for key in self.fields if key.include_in_insert]
274
273
  )
275
274
  try:
276
- self.fields.id
275
+ _ = self.fields.id
277
276
  output = ", ".join(
278
277
  ["[" + field.name + "] AS " + field.name for field in self.fields]
279
278
  )
@@ -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 Callable, Generic, Iterator, TypeVar
5
+ from typing import Generic, TypeVar
5
6
 
6
7
  from apexdevkit.error import DoesNotExistError
7
8
  from apexdevkit.formatter import Formatter
@@ -75,22 +76,34 @@ class MultipleRepositoryBuilder(Generic[ItemT]):
75
76
  self,
76
77
  repository: Repository[ItemT],
77
78
  condition: Callable[[ItemT], bool] = lambda item: True,
78
- formatter: Formatter[ItemT, ItemT] = NoFormatter[ItemT](),
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
- + [_InnerRepository(repository, condition, formatter, id_prefix)]
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
97
  condition: Callable[[ItemT], bool] = lambda item: True,
90
- formatter: Formatter[ItemT, ItemT] = NoFormatter[ItemT](),
98
+ formatter: Formatter[ItemT, ItemT] | None = None,
91
99
  id_prefix: str = "",
92
100
  ) -> MultipleRepositoryBuilder[ItemT]:
93
- return self.with_repository(repository, condition, formatter, id_prefix)
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)
@@ -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, Iterator, Mapping
5
+ from typing import Any
5
6
 
6
7
 
7
8
  @dataclass(frozen=True)
@@ -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, Iterable, Iterator, Mapping
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:
@@ -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})
@@ -1,8 +1,9 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import logging.config
4
+ from collections.abc import Callable
4
5
  from dataclasses import dataclass, field
5
- from typing import Any, Callable
6
+ from typing import Any
6
7
 
7
8
  import sentry_sdk
8
9
  import uvicorn
@@ -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, Iterable, Iterator, Protocol, TypeVar
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, ContextManager, Self
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) -> ContextManager[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, Type, TypeVar
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: Type[ItemT] = field()
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: Type[Value] = field(default=Value)
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: Type[NumericValue] = field(default=NumericValue)
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: Type[StringValue] = field(default=StringValue)
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: Type[DateValue] = field(default=DateValue)
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: Type[Leaf] = field(default=Leaf)
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: Type[Operator] = field(default=Operator)
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: Type[Sort] = field(default=Sort)
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: Type[Page] = field(default=Page)
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: Type[Filter] = field(default=Filter)
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: Type[QueryOptions] = field(default=QueryOptions)
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: Type[AggregationOption] = field(default=AggregationOption)
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, Iterable, Self
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
- [tool.poetry]
1
+ [project]
2
2
  name = "apexdevkit"
3
- version = "1.22.2"
3
+ version = "1.23.1"
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,16 @@ exclude = [
48
48
  "venv",
49
49
  ]
50
50
 
51
- lint.select = ["E", "F", "I"]
52
- lint.ignore = []
53
- lint.fixable = ["A", "B", "C", "D", "E", "F", "I"]
54
- lint.unfixable = []
51
+ [tool.ruff.lint]
52
+ select = [
53
+ "B", # flake8-bugbear
54
+ "C4", # flake8-comprehensions
55
+ "E", # pycodestyle errors
56
+ "F", # pyflakes
57
+ "I", # isort
58
+ "UP", # pyupgrade
59
+ "W", # pycodestyle warnings
60
+ ]
55
61
 
56
62
  [tool.ruff.lint.mccabe]
57
63
  max-complexity = 10
File without changes
File without changes