TypeDAL 5.1.1__tar.gz → 5.1.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.
- {typedal-5.1.1 → typedal-5.1.2}/PKG-INFO +1 -1
- {typedal-5.1.1 → typedal-5.1.2}/pyproject.toml +1 -1
- {typedal-5.1.1 → typedal-5.1.2}/pyproject.toml.orig +1 -1
- {typedal-5.1.1 → typedal-5.1.2}/src/typedal/cli.py +1 -1
- {typedal-5.1.1 → typedal-5.1.2}/src/typedal/core.py +15 -13
- {typedal-5.1.1 → typedal-5.1.2}/src/typedal/query_builder.py +11 -7
- {typedal-5.1.1 → typedal-5.1.2}/src/typedal/relationships.py +4 -2
- {typedal-5.1.1 → typedal-5.1.2}/src/typedal/rows.py +2 -3
- {typedal-5.1.1 → typedal-5.1.2}/src/typedal/serializers/typescript.py +1 -1
- {typedal-5.1.1 → typedal-5.1.2}/src/typedal/tables.py +1 -1
- {typedal-5.1.1 → typedal-5.1.2}/README.md +0 -0
- {typedal-5.1.1 → typedal-5.1.2}/src/typedal/__about__.py +0 -0
- {typedal-5.1.1 → typedal-5.1.2}/src/typedal/__init__.py +0 -0
- {typedal-5.1.1 → typedal-5.1.2}/src/typedal/asynchronous.py +0 -0
- {typedal-5.1.1 → typedal-5.1.2}/src/typedal/caching.py +0 -0
- {typedal-5.1.1 → typedal-5.1.2}/src/typedal/config.py +0 -0
- {typedal-5.1.1 → typedal-5.1.2}/src/typedal/constants.py +0 -0
- {typedal-5.1.1 → typedal-5.1.2}/src/typedal/define.py +0 -0
- {typedal-5.1.1 → typedal-5.1.2}/src/typedal/enum_helpers.py +0 -0
- {typedal-5.1.1 → typedal-5.1.2}/src/typedal/fields.py +0 -0
- {typedal-5.1.1 → typedal-5.1.2}/src/typedal/for_py4web.py +0 -0
- {typedal-5.1.1 → typedal-5.1.2}/src/typedal/for_web2py.py +0 -0
- {typedal-5.1.1 → typedal-5.1.2}/src/typedal/helpers.py +0 -0
- {typedal-5.1.1 → typedal-5.1.2}/src/typedal/mixins.py +0 -0
- {typedal-5.1.1 → typedal-5.1.2}/src/typedal/py.typed +0 -0
- {typedal-5.1.1 → typedal-5.1.2}/src/typedal/serializers/as_json.py +0 -0
- {typedal-5.1.1 → typedal-5.1.2}/src/typedal/types.py +0 -0
- {typedal-5.1.1 → typedal-5.1.2}/src/typedal/warnings.py +0 -0
- {typedal-5.1.1 → typedal-5.1.2}/src/typedal/web2py_py4web_shared.py +0 -0
|
@@ -227,7 +227,7 @@ def setup(
|
|
|
227
227
|
data.pop("connection", None)
|
|
228
228
|
|
|
229
229
|
# ignore any None:
|
|
230
|
-
old_contents["tool"]["typedal"] = {k: v for k, v in data.items() if v is not None}
|
|
230
|
+
old_contents["tool"]["typedal"] = {k: v for k, v in data.items() if v is not None}
|
|
231
231
|
|
|
232
232
|
with toml_path.open("w") as f:
|
|
233
233
|
tomlkit.dump(old_contents, f)
|
|
@@ -34,7 +34,7 @@ from .helpers import (
|
|
|
34
34
|
from .serializers.typescript import TypedDictRegistry
|
|
35
35
|
|
|
36
36
|
# noinspection PyUnusedImports
|
|
37
|
-
from .types import CacheStatus, Field, Template
|
|
37
|
+
from .types import CacheStatus, Expression, Field, Template
|
|
38
38
|
|
|
39
39
|
try:
|
|
40
40
|
# python 3.14+
|
|
@@ -46,10 +46,10 @@ except ImportError: # pragma: no cover
|
|
|
46
46
|
if t.TYPE_CHECKING:
|
|
47
47
|
from .fields import TypedField
|
|
48
48
|
from .query_builder import QueryBuilder
|
|
49
|
-
from .types import AnyDict, DefineKwargs,
|
|
49
|
+
from .types import AnyDict, DefineKwargs, Rows, Set, T_Query, Table
|
|
50
50
|
|
|
51
51
|
|
|
52
|
-
def _expression_subclasses() -> t.Iterator[type]:
|
|
52
|
+
def _expression_subclasses() -> t.Iterator[type[Expression]]:
|
|
53
53
|
"""
|
|
54
54
|
Yield Expression and every (nested) subclass currently loaded, e.g. Field and TypedField.
|
|
55
55
|
"""
|
|
@@ -100,7 +100,7 @@ def _purge_dialect_expressions(adapter: t.Any) -> None:
|
|
|
100
100
|
# because then they will have different globals and it breaks!
|
|
101
101
|
|
|
102
102
|
|
|
103
|
-
def evaluate_forward_reference_312(fw_ref: ForwardRef, namespace:
|
|
103
|
+
def evaluate_forward_reference_312(fw_ref: ForwardRef, namespace: t.Mapping[str, type]) -> type: # pragma: no cover
|
|
104
104
|
"""
|
|
105
105
|
Extract the original type from a forward reference string.
|
|
106
106
|
|
|
@@ -110,13 +110,13 @@ def evaluate_forward_reference_312(fw_ref: ForwardRef, namespace: dict[str, type
|
|
|
110
110
|
type,
|
|
111
111
|
fw_ref._evaluate( # ty: ignore[deprecated]
|
|
112
112
|
localns=locals(),
|
|
113
|
-
globalns=globals() | namespace,
|
|
113
|
+
globalns=globals() | dict(namespace),
|
|
114
114
|
recursive_guard=frozenset(),
|
|
115
115
|
),
|
|
116
116
|
)
|
|
117
117
|
|
|
118
118
|
|
|
119
|
-
def evaluate_forward_reference_313(fw_ref: ForwardRef, namespace:
|
|
119
|
+
def evaluate_forward_reference_313(fw_ref: ForwardRef, namespace: t.Mapping[str, type]) -> type: # pragma: no cover
|
|
120
120
|
"""
|
|
121
121
|
Extract the original type from a forward reference string.
|
|
122
122
|
|
|
@@ -126,14 +126,14 @@ def evaluate_forward_reference_313(fw_ref: ForwardRef, namespace: dict[str, type
|
|
|
126
126
|
type,
|
|
127
127
|
fw_ref._evaluate( # ty: ignore[deprecated]
|
|
128
128
|
localns=locals(),
|
|
129
|
-
globalns=globals() | namespace,
|
|
129
|
+
globalns=globals() | dict(namespace),
|
|
130
130
|
recursive_guard=frozenset(),
|
|
131
131
|
type_params=(), # suggested since 3.13 (warning) and not supported before. Mandatory after 1.15!
|
|
132
132
|
),
|
|
133
133
|
)
|
|
134
134
|
|
|
135
135
|
|
|
136
|
-
def evaluate_forward_reference_314(fw_ref: ForwardRef, namespace:
|
|
136
|
+
def evaluate_forward_reference_314(fw_ref: ForwardRef, namespace: t.Mapping[str, type]) -> type: # pragma: no cover
|
|
137
137
|
"""
|
|
138
138
|
Extract the original type from a forward reference string.
|
|
139
139
|
|
|
@@ -143,7 +143,7 @@ def evaluate_forward_reference_314(fw_ref: ForwardRef, namespace: dict[str, type
|
|
|
143
143
|
type,
|
|
144
144
|
fw_ref.evaluate(
|
|
145
145
|
locals=locals(),
|
|
146
|
-
globals=globals() | namespace,
|
|
146
|
+
globals=globals() | dict(namespace),
|
|
147
147
|
type_params=(),
|
|
148
148
|
),
|
|
149
149
|
)
|
|
@@ -151,7 +151,7 @@ def evaluate_forward_reference_314(fw_ref: ForwardRef, namespace: dict[str, type
|
|
|
151
151
|
|
|
152
152
|
def evaluate_forward_reference(
|
|
153
153
|
fw_ref: ForwardRef,
|
|
154
|
-
namespace:
|
|
154
|
+
namespace: t.Mapping[str, type] | None = None,
|
|
155
155
|
) -> type: # pragma: no cover
|
|
156
156
|
"""
|
|
157
157
|
Extract the original type from a forward reference string.
|
|
@@ -166,7 +166,7 @@ def evaluate_forward_reference(
|
|
|
166
166
|
return evaluate_forward_reference_314(fw_ref, namespace=namespace or {})
|
|
167
167
|
|
|
168
168
|
|
|
169
|
-
def resolve_annotation_313(ftype: str, namespace:
|
|
169
|
+
def resolve_annotation_313(ftype: str, namespace: t.Mapping[str, type] | None = None) -> type: # pragma: no cover
|
|
170
170
|
"""
|
|
171
171
|
Resolve an annotation that's in string representation.
|
|
172
172
|
|
|
@@ -176,7 +176,7 @@ def resolve_annotation_313(ftype: str, namespace: dict[str, type] | None = None)
|
|
|
176
176
|
return evaluate_forward_reference(fw_ref, namespace=namespace)
|
|
177
177
|
|
|
178
178
|
|
|
179
|
-
def resolve_annotation_314(ftype: str, namespace:
|
|
179
|
+
def resolve_annotation_314(ftype: str, namespace: t.Mapping[str, type] | None = None) -> type: # pragma: no cover
|
|
180
180
|
"""
|
|
181
181
|
Resolve an annotation that's in string representation.
|
|
182
182
|
|
|
@@ -186,7 +186,7 @@ def resolve_annotation_314(ftype: str, namespace: dict[str, type] | None = None)
|
|
|
186
186
|
return evaluate_forward_reference(fw_ref, namespace=namespace)
|
|
187
187
|
|
|
188
188
|
|
|
189
|
-
def resolve_annotation(ftype: str, namespace:
|
|
189
|
+
def resolve_annotation(ftype: str, namespace: t.Mapping[str, type] | None = None) -> type: # pragma: no cover
|
|
190
190
|
"""
|
|
191
191
|
Resolve an annotation that's in string representation.
|
|
192
192
|
|
|
@@ -220,6 +220,8 @@ if t.TYPE_CHECKING:
|
|
|
220
220
|
|
|
221
221
|
def has_representer(self, field_type: str) -> bool: ...
|
|
222
222
|
|
|
223
|
+
def represent(self, name: str, *args: t.Any, **kwargs: t.Any) -> str: ...
|
|
224
|
+
|
|
223
225
|
# pydal exposes dynamic table attributes like `db.my_table`.
|
|
224
226
|
# this keeps type checkers from flagging these as missing attributes.
|
|
225
227
|
def __getattr__(self, item: str) -> "Table": ...
|
|
@@ -187,7 +187,7 @@ class QueryBuilder[T_MetaInstance: _TypedTable](Select):
|
|
|
187
187
|
"""
|
|
188
188
|
Return a clone of this builder with permission overrides merged in.
|
|
189
189
|
"""
|
|
190
|
-
if not permissions and self:
|
|
190
|
+
if not permissions and self: # ty: ignore[redundant-condition]
|
|
191
191
|
warn_noop("permissions")
|
|
192
192
|
return self
|
|
193
193
|
|
|
@@ -1299,7 +1299,8 @@ class QueryBuilder[T_MetaInstance: _TypedTable](Select):
|
|
|
1299
1299
|
def __count(
|
|
1300
1300
|
self,
|
|
1301
1301
|
db: TypeDAL,
|
|
1302
|
-
distinct: t.
|
|
1302
|
+
distinct: bool | Field | TypedField[t.Any] = False,
|
|
1303
|
+
*,
|
|
1303
1304
|
include_left_for_distinct: bool = True,
|
|
1304
1305
|
) -> Query:
|
|
1305
1306
|
# internal, shared logic between .count and ._count
|
|
@@ -1323,9 +1324,11 @@ class QueryBuilder[T_MetaInstance: _TypedTable](Select):
|
|
|
1323
1324
|
|
|
1324
1325
|
return query
|
|
1325
1326
|
|
|
1326
|
-
def count(self, distinct: t.
|
|
1327
|
+
def count(self, distinct: bool | Field | TypedField[t.Any] = False) -> int:
|
|
1327
1328
|
"""
|
|
1328
1329
|
Return the amount of rows matching the current query.
|
|
1330
|
+
|
|
1331
|
+
Passing a field counts its distinct values.
|
|
1329
1332
|
"""
|
|
1330
1333
|
require_permission(self._permissions, "read")
|
|
1331
1334
|
db = self._get_db()
|
|
@@ -1333,7 +1336,7 @@ class QueryBuilder[T_MetaInstance: _TypedTable](Select):
|
|
|
1333
1336
|
|
|
1334
1337
|
return db(query).count(distinct)
|
|
1335
1338
|
|
|
1336
|
-
def _count(self, distinct: t.
|
|
1339
|
+
def _count(self, distinct: bool | Field | TypedField[t.Any] = False) -> str:
|
|
1337
1340
|
"""
|
|
1338
1341
|
Return the SQL for .count().
|
|
1339
1342
|
"""
|
|
@@ -1359,8 +1362,9 @@ class QueryBuilder[T_MetaInstance: _TypedTable](Select):
|
|
|
1359
1362
|
return self.count()
|
|
1360
1363
|
|
|
1361
1364
|
db = self._get_db()
|
|
1362
|
-
|
|
1363
|
-
|
|
1365
|
+
distinct = t.cast(TypedField[int], self.model.id)
|
|
1366
|
+
query = self.__count(db, distinct=distinct, include_left_for_distinct=False)
|
|
1367
|
+
return db(query).count(distinct)
|
|
1364
1368
|
|
|
1365
1369
|
def __paginate(
|
|
1366
1370
|
self,
|
|
@@ -1554,7 +1558,7 @@ class QueryBuilder[T_MetaInstance: _TypedTable](Select):
|
|
|
1554
1558
|
column = t.cast(t.Callable[..., list[T]], self.column)
|
|
1555
1559
|
return await run_async(self._get_db(), column, field, **options)
|
|
1556
1560
|
|
|
1557
|
-
async def count_async(self, distinct: t.
|
|
1561
|
+
async def count_async(self, distinct: bool | Field | TypedField[t.Any] = False) -> int:
|
|
1558
1562
|
"""
|
|
1559
1563
|
Async twin of `count()`.
|
|
1560
1564
|
"""
|
|
@@ -253,10 +253,12 @@ class Relationship[To_Type]:
|
|
|
253
253
|
# relationship queried on class, that's allowed
|
|
254
254
|
return self
|
|
255
255
|
|
|
256
|
+
db = instance._db
|
|
257
|
+
|
|
256
258
|
# instance: TypedTable instance
|
|
257
259
|
# owner: TypedTable class
|
|
258
260
|
|
|
259
|
-
if not self.name: # pragma: no cover
|
|
261
|
+
if not (self.name and db): # pragma: no cover
|
|
260
262
|
raise ValueError("Relationship does not seem to be connected to a table field.")
|
|
261
263
|
|
|
262
264
|
# Handle different lazy policies
|
|
@@ -284,7 +286,7 @@ class Relationship[To_Type]:
|
|
|
284
286
|
|
|
285
287
|
# For "tolerate" and "allow", we fetch the data
|
|
286
288
|
try:
|
|
287
|
-
resolved_table = self.get_table(
|
|
289
|
+
resolved_table = self.get_table(db)
|
|
288
290
|
|
|
289
291
|
builder = owner.where(id=instance.id).join(self.name)
|
|
290
292
|
if issubclass(resolved_table, TypedTable) or isinstance(resolved_table, Table):
|
|
@@ -10,6 +10,7 @@ import typing as t
|
|
|
10
10
|
|
|
11
11
|
from .asynchronous import run_async
|
|
12
12
|
from .core import TypeDAL
|
|
13
|
+
from .fields import TypedField
|
|
13
14
|
from .helpers import mktable
|
|
14
15
|
from .query_builder import QueryBuilder
|
|
15
16
|
from .serializers import as_json
|
|
@@ -563,7 +564,7 @@ class TypedSet(Set): # pragma: no cover
|
|
|
563
564
|
This class is not actually used, only 'cast' by TypeDAL.__call__
|
|
564
565
|
"""
|
|
565
566
|
|
|
566
|
-
def count(self, distinct: bool |
|
|
567
|
+
def count(self, distinct: bool | Field | TypedField[t.Any] = False, cache: AnyDict | None = None) -> int:
|
|
567
568
|
"""
|
|
568
569
|
Count returns an int.
|
|
569
570
|
"""
|
|
@@ -585,5 +586,3 @@ class TypedSet(Set): # pragma: no cover
|
|
|
585
586
|
|
|
586
587
|
|
|
587
588
|
# note: these imports exist at the bottom of this file to prevent circular import issues:
|
|
588
|
-
|
|
589
|
-
from .fields import TypedField # noqa: E402
|
|
@@ -31,7 +31,7 @@ class TypedDictRegistry(Singleton):
|
|
|
31
31
|
def __init__(self) -> None:
|
|
32
32
|
"""Initialize the singleton registry and optional shared typtyp world."""
|
|
33
33
|
self._types: dict[type, type[dict[str, t.Any]]] = {}
|
|
34
|
-
self._world = typtyp.World() if typtyp else None #
|
|
34
|
+
self._world = typtyp.World() if typtyp else None # ty: ignore[redundant-condition]
|
|
35
35
|
self._names: set[str] = set()
|
|
36
36
|
|
|
37
37
|
@property
|
|
@@ -1152,7 +1152,7 @@ class TypedTable(_TypedTable, metaclass=TableMeta):
|
|
|
1152
1152
|
"after_delete": cls._after_delete,
|
|
1153
1153
|
}
|
|
1154
1154
|
|
|
1155
|
-
def _setup_instance_methods(self) -> None:
|
|
1155
|
+
def _setup_instance_methods(self: t.Self | type[t.Self]) -> None:
|
|
1156
1156
|
# use setattr instead of self.x = y to make the typecheckers happier
|
|
1157
1157
|
setattr(self, "as_dict", self._as_dict)
|
|
1158
1158
|
setattr(self, "__json__", self._as_json)
|
|
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
|