TypeDAL 3.1.4__py3-none-any.whl → 3.3.0__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.
Potentially problematic release.
This version of TypeDAL might be problematic. Click here for more details.
- typedal/__about__.py +1 -1
- typedal/caching.py +1 -1
- typedal/cli.py +1 -1
- typedal/config.py +1 -1
- typedal/core.py +37 -36
- typedal/mixins.py +43 -6
- typedal/types.py +62 -1
- {typedal-3.1.4.dist-info → typedal-3.3.0.dist-info}/METADATA +2 -1
- typedal-3.3.0.dist-info/RECORD +19 -0
- typedal-3.1.4.dist-info/RECORD +0 -19
- {typedal-3.1.4.dist-info → typedal-3.3.0.dist-info}/WHEEL +0 -0
- {typedal-3.1.4.dist-info → typedal-3.3.0.dist-info}/entry_points.txt +0 -0
typedal/__about__.py
CHANGED
typedal/caching.py
CHANGED
typedal/cli.py
CHANGED
|
@@ -24,7 +24,7 @@ try:
|
|
|
24
24
|
import tomlkit
|
|
25
25
|
import typer
|
|
26
26
|
from tabulate import tabulate
|
|
27
|
-
except ImportError as e:
|
|
27
|
+
except ImportError as e:
|
|
28
28
|
# ImportWarning is hidden by default
|
|
29
29
|
warnings.warn(
|
|
30
30
|
"`migrations` extra not installed. Please run `pip install typedal[migrations]` to fix this.",
|
typedal/config.py
CHANGED
|
@@ -17,7 +17,7 @@ from dotenv import dotenv_values, find_dotenv
|
|
|
17
17
|
|
|
18
18
|
from .types import AnyDict
|
|
19
19
|
|
|
20
|
-
if typing.TYPE_CHECKING:
|
|
20
|
+
if typing.TYPE_CHECKING:
|
|
21
21
|
from edwh_migrate import Config as MigrateConfig
|
|
22
22
|
from pydal2sql.typer_support import Config as P2SConfig
|
|
23
23
|
|
typedal/core.py
CHANGED
|
@@ -23,7 +23,7 @@ from pydal.objects import Field as _Field
|
|
|
23
23
|
from pydal.objects import Query as _Query
|
|
24
24
|
from pydal.objects import Row
|
|
25
25
|
from pydal.objects import Table as _Table
|
|
26
|
-
from typing_extensions import Self
|
|
26
|
+
from typing_extensions import Self, Unpack
|
|
27
27
|
|
|
28
28
|
from .config import TypeDALConfig, load_config
|
|
29
29
|
from .helpers import (
|
|
@@ -58,6 +58,8 @@ from .types import (
|
|
|
58
58
|
Pagination,
|
|
59
59
|
Query,
|
|
60
60
|
Rows,
|
|
61
|
+
SelectKwargs,
|
|
62
|
+
Table,
|
|
61
63
|
Validator,
|
|
62
64
|
_Types,
|
|
63
65
|
)
|
|
@@ -753,25 +755,6 @@ class TypeDAL(pydal.DAL): # type: ignore
|
|
|
753
755
|
return to_snake(camel)
|
|
754
756
|
|
|
755
757
|
|
|
756
|
-
class TableProtocol(typing.Protocol): # pragma: no cover
|
|
757
|
-
"""
|
|
758
|
-
Make mypy happy.
|
|
759
|
-
"""
|
|
760
|
-
|
|
761
|
-
id: "TypedField[int]"
|
|
762
|
-
|
|
763
|
-
def __getitem__(self, item: str) -> Field:
|
|
764
|
-
"""
|
|
765
|
-
Tell mypy a Table supports dictionary notation for columns.
|
|
766
|
-
"""
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
class Table(_Table, TableProtocol): # type: ignore
|
|
770
|
-
"""
|
|
771
|
-
Make mypy happy.
|
|
772
|
-
"""
|
|
773
|
-
|
|
774
|
-
|
|
775
758
|
class TableMeta(type):
|
|
776
759
|
"""
|
|
777
760
|
This metaclass contains functionality on table classes, that doesn't exist on its instances.
|
|
@@ -953,10 +936,7 @@ class TableMeta(type):
|
|
|
953
936
|
"""
|
|
954
937
|
table = self._ensure_table_defined()
|
|
955
938
|
|
|
956
|
-
|
|
957
|
-
result = table.validate_and_update(query, **fields)
|
|
958
|
-
except Exception as e:
|
|
959
|
-
result = {"errors": {"exception": str(e)}}
|
|
939
|
+
result = table.validate_and_update(query, **fields)
|
|
960
940
|
|
|
961
941
|
if errors := result.get("errors"):
|
|
962
942
|
return None, errors
|
|
@@ -1029,6 +1009,12 @@ class TableMeta(type):
|
|
|
1029
1009
|
"""
|
|
1030
1010
|
return QueryBuilder(self).first()
|
|
1031
1011
|
|
|
1012
|
+
def first_or_fail(self: typing.Type[T_MetaInstance]) -> T_MetaInstance:
|
|
1013
|
+
"""
|
|
1014
|
+
See QueryBuilder.first_or_fail!
|
|
1015
|
+
"""
|
|
1016
|
+
return QueryBuilder(self).first_or_fail()
|
|
1017
|
+
|
|
1032
1018
|
def join(
|
|
1033
1019
|
self: typing.Type[T_MetaInstance],
|
|
1034
1020
|
*fields: str | typing.Type["TypedTable"],
|
|
@@ -1156,7 +1142,7 @@ class TableMeta(type):
|
|
|
1156
1142
|
# @typing.dataclass_transform()
|
|
1157
1143
|
|
|
1158
1144
|
|
|
1159
|
-
class TypedField(typing.Generic[T_Value]): # pragma: no cover
|
|
1145
|
+
class TypedField(Expression, typing.Generic[T_Value]): # pragma: no cover
|
|
1160
1146
|
"""
|
|
1161
1147
|
Typed version of pydal.Field, which will be converted to a normal Field in the background.
|
|
1162
1148
|
"""
|
|
@@ -1179,7 +1165,7 @@ class TypedField(typing.Generic[T_Value]): # pragma: no cover
|
|
|
1179
1165
|
"""
|
|
1180
1166
|
self._type = _type
|
|
1181
1167
|
self.kwargs = settings
|
|
1182
|
-
super().__init__()
|
|
1168
|
+
# super().__init__()
|
|
1183
1169
|
|
|
1184
1170
|
@typing.overload
|
|
1185
1171
|
def __get__(self, instance: T_MetaInstance, owner: typing.Type[T_MetaInstance]) -> T_Value: # pragma: no cover
|
|
@@ -1323,6 +1309,17 @@ class TypedField(typing.Generic[T_Value]): # pragma: no cover
|
|
|
1323
1309
|
|
|
1324
1310
|
return typing.cast(Expression, ~self._field)
|
|
1325
1311
|
|
|
1312
|
+
def lower(self) -> Expression:
|
|
1313
|
+
"""
|
|
1314
|
+
For string-fields: compare lowercased values.
|
|
1315
|
+
"""
|
|
1316
|
+
if not self._field: # pragma: no cover
|
|
1317
|
+
raise ValueError("Unbound Field can not be lowered!")
|
|
1318
|
+
|
|
1319
|
+
return typing.cast(Expression, self._field.lower())
|
|
1320
|
+
|
|
1321
|
+
# ... etc
|
|
1322
|
+
|
|
1326
1323
|
|
|
1327
1324
|
class _TypedTable:
|
|
1328
1325
|
"""
|
|
@@ -1377,7 +1374,7 @@ class TypedTable(_TypedTable, metaclass=TableMeta):
|
|
|
1377
1374
|
|
|
1378
1375
|
def __new__(
|
|
1379
1376
|
cls, row_or_id: typing.Union[Row, Query, pydal.objects.Set, int, str, None, "TypedTable"] = None, **filters: Any
|
|
1380
|
-
) ->
|
|
1377
|
+
) -> typing.Self:
|
|
1381
1378
|
"""
|
|
1382
1379
|
Create a Typed Rows model instance from an existing row, ID or query.
|
|
1383
1380
|
|
|
@@ -1391,7 +1388,8 @@ class TypedTable(_TypedTable, metaclass=TableMeta):
|
|
|
1391
1388
|
|
|
1392
1389
|
if isinstance(row_or_id, TypedTable):
|
|
1393
1390
|
# existing typed table instance!
|
|
1394
|
-
return row_or_id
|
|
1391
|
+
return typing.cast(Self, row_or_id)
|
|
1392
|
+
|
|
1395
1393
|
elif isinstance(row_or_id, pydal.objects.Row):
|
|
1396
1394
|
row = row_or_id
|
|
1397
1395
|
elif row_or_id is not None:
|
|
@@ -2052,7 +2050,7 @@ class QueryBuilder(typing.Generic[T_MetaInstance]):
|
|
|
2052
2050
|
model: typing.Type[T_MetaInstance]
|
|
2053
2051
|
query: Query
|
|
2054
2052
|
select_args: list[Any]
|
|
2055
|
-
select_kwargs:
|
|
2053
|
+
select_kwargs: SelectKwargs
|
|
2056
2054
|
relationships: dict[str, Relationship[Any]]
|
|
2057
2055
|
metadata: Metadata
|
|
2058
2056
|
|
|
@@ -2061,7 +2059,7 @@ class QueryBuilder(typing.Generic[T_MetaInstance]):
|
|
|
2061
2059
|
model: typing.Type[T_MetaInstance],
|
|
2062
2060
|
add_query: Optional[Query] = None,
|
|
2063
2061
|
select_args: Optional[list[Any]] = None,
|
|
2064
|
-
select_kwargs: Optional[
|
|
2062
|
+
select_kwargs: Optional[SelectKwargs] = None,
|
|
2065
2063
|
relationships: dict[str, Relationship[Any]] = None,
|
|
2066
2064
|
metadata: Metadata = None,
|
|
2067
2065
|
):
|
|
@@ -2111,7 +2109,7 @@ class QueryBuilder(typing.Generic[T_MetaInstance]):
|
|
|
2111
2109
|
add_query: Optional[Query] = None,
|
|
2112
2110
|
overwrite_query: Optional[Query] = None,
|
|
2113
2111
|
select_args: Optional[list[Any]] = None,
|
|
2114
|
-
select_kwargs: Optional[
|
|
2112
|
+
select_kwargs: Optional[SelectKwargs] = None,
|
|
2115
2113
|
relationships: dict[str, Relationship[Any]] = None,
|
|
2116
2114
|
metadata: Metadata = None,
|
|
2117
2115
|
) -> "QueryBuilder[T_MetaInstance]":
|
|
@@ -2124,7 +2122,7 @@ class QueryBuilder(typing.Generic[T_MetaInstance]):
|
|
|
2124
2122
|
(self.metadata | (metadata or {})) if metadata else self.metadata,
|
|
2125
2123
|
)
|
|
2126
2124
|
|
|
2127
|
-
def select(self, *fields: Any, **options:
|
|
2125
|
+
def select(self, *fields: Any, **options: Unpack[SelectKwargs]) -> "QueryBuilder[T_MetaInstance]":
|
|
2128
2126
|
"""
|
|
2129
2127
|
Fields: database columns by name ('id'), by field reference (table.id) or other (e.g. table.ALL).
|
|
2130
2128
|
|
|
@@ -2313,7 +2311,7 @@ class QueryBuilder(typing.Generic[T_MetaInstance]):
|
|
|
2313
2311
|
db = self._get_db()
|
|
2314
2312
|
return str(db(self.query)._update(**fields))
|
|
2315
2313
|
|
|
2316
|
-
def _before_query(self, mut_metadata: Metadata, add_id: bool = True) -> tuple[Query, list[Any],
|
|
2314
|
+
def _before_query(self, mut_metadata: Metadata, add_id: bool = True) -> tuple[Query, list[Any], SelectKwargs]:
|
|
2317
2315
|
select_args = [self._select_arg_convert(_) for _ in self.select_args] or [self.model.ALL]
|
|
2318
2316
|
select_kwargs = self.select_kwargs.copy()
|
|
2319
2317
|
query = self.query
|
|
@@ -2432,7 +2430,7 @@ class QueryBuilder(typing.Generic[T_MetaInstance]):
|
|
|
2432
2430
|
self,
|
|
2433
2431
|
query: Query,
|
|
2434
2432
|
select_args: list[Any],
|
|
2435
|
-
select_kwargs:
|
|
2433
|
+
select_kwargs: SelectKwargs,
|
|
2436
2434
|
metadata: Metadata,
|
|
2437
2435
|
) -> tuple[Query, list[Any]]:
|
|
2438
2436
|
db = self._get_db()
|
|
@@ -2450,13 +2448,16 @@ class QueryBuilder(typing.Generic[T_MetaInstance]):
|
|
|
2450
2448
|
other = other.with_alias(f"{key}_{hash(relation)}")
|
|
2451
2449
|
join.append(other.on(relation.condition(model, other)))
|
|
2452
2450
|
|
|
2453
|
-
if limitby := select_kwargs.pop("limitby",
|
|
2451
|
+
if limitby := select_kwargs.pop("limitby", ()):
|
|
2452
|
+
|
|
2454
2453
|
# if limitby + relationships:
|
|
2455
2454
|
# 1. get IDs of main table entries that match 'query'
|
|
2456
2455
|
# 2. change query to .belongs(id)
|
|
2457
2456
|
# 3. add joins etc
|
|
2458
2457
|
|
|
2459
|
-
kwargs = {"limitby": limitby}
|
|
2458
|
+
kwargs: SelectKwargs = select_kwargs | {"limitby": limitby}
|
|
2459
|
+
# if orderby := select_kwargs.get("orderby"):
|
|
2460
|
+
# kwargs["orderby"] = orderby
|
|
2460
2461
|
|
|
2461
2462
|
if join:
|
|
2462
2463
|
kwargs["join"] = join
|
typedal/mixins.py
CHANGED
|
@@ -7,13 +7,20 @@ Mixins can add reusable fields and behavior (optimally both, otherwise it doesn'
|
|
|
7
7
|
import base64
|
|
8
8
|
import os
|
|
9
9
|
import typing
|
|
10
|
+
import warnings
|
|
10
11
|
from datetime import datetime
|
|
11
|
-
from typing import Any
|
|
12
|
+
from typing import Any, Optional
|
|
12
13
|
|
|
13
14
|
from slugify import slugify
|
|
14
15
|
|
|
15
|
-
from .core import
|
|
16
|
-
|
|
16
|
+
from .core import ( # noqa F401 - used by example in docstring
|
|
17
|
+
QueryBuilder,
|
|
18
|
+
T_MetaInstance,
|
|
19
|
+
TableMeta,
|
|
20
|
+
TypeDAL,
|
|
21
|
+
TypedTable,
|
|
22
|
+
_TypedTable,
|
|
23
|
+
)
|
|
17
24
|
from .fields import DatetimeField, StringField
|
|
18
25
|
from .types import OpRow, Set
|
|
19
26
|
|
|
@@ -79,7 +86,7 @@ class SlugMixin(Mixin):
|
|
|
79
86
|
Some random bytes are added at the end to prevent duplicates.
|
|
80
87
|
|
|
81
88
|
Example:
|
|
82
|
-
>>> class MyTable(TypedTable, SlugMixin, slug_field="some_name"):
|
|
89
|
+
>>> class MyTable(TypedTable, SlugMixin, slug_field="some_name", slug_suffix_length=8):
|
|
83
90
|
>>> some_name: str
|
|
84
91
|
>>> ...
|
|
85
92
|
"""
|
|
@@ -95,11 +102,11 @@ class SlugMixin(Mixin):
|
|
|
95
102
|
},
|
|
96
103
|
) # set via init subclass
|
|
97
104
|
|
|
98
|
-
def __init_subclass__(cls, slug_field: str = None,
|
|
105
|
+
def __init_subclass__(cls, slug_field: str = None, slug_suffix_length: int = 0, **kw: Any) -> None:
|
|
99
106
|
"""
|
|
100
107
|
Bind 'slug field' option to be used later (on_define).
|
|
101
108
|
|
|
102
|
-
You can control the length of the random suffix with the `
|
|
109
|
+
You can control the length of the random suffix with the `slug_suffix_length` option (0 is no suffix).
|
|
103
110
|
"""
|
|
104
111
|
# unfortunately, PyCharm and mypy do not recognize/autocomplete/typecheck init subclass (keyword) arguments.
|
|
105
112
|
if slug_field is None:
|
|
@@ -108,6 +115,14 @@ class SlugMixin(Mixin):
|
|
|
108
115
|
"e.g. `class MyClass(TypedTable, SlugMixin, slug_field='title'): ...`"
|
|
109
116
|
)
|
|
110
117
|
|
|
118
|
+
if "slug_suffix" in kw:
|
|
119
|
+
warnings.warn(
|
|
120
|
+
"The 'slug_suffix' option is deprecated, use 'slug_suffix_length' instead.",
|
|
121
|
+
DeprecationWarning,
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
slug_suffix = slug_suffix_length or kw.get("slug_suffix", 0)
|
|
125
|
+
|
|
111
126
|
cls.__settings__ = {
|
|
112
127
|
"slug_field": slug_field,
|
|
113
128
|
"slug_suffix": slug_suffix,
|
|
@@ -133,3 +148,25 @@ class SlugMixin(Mixin):
|
|
|
133
148
|
row["slug"] = slugify(generated_slug)
|
|
134
149
|
|
|
135
150
|
cls._before_insert.append(generate_slug_before_insert)
|
|
151
|
+
|
|
152
|
+
@classmethod
|
|
153
|
+
def from_slug(cls: typing.Type[T_MetaInstance], slug: str, join: bool = True) -> Optional[T_MetaInstance]:
|
|
154
|
+
"""
|
|
155
|
+
Find a row by its slug.
|
|
156
|
+
"""
|
|
157
|
+
builder = cls.where(slug=slug)
|
|
158
|
+
if join:
|
|
159
|
+
builder = builder.join()
|
|
160
|
+
|
|
161
|
+
return builder.first()
|
|
162
|
+
|
|
163
|
+
@classmethod
|
|
164
|
+
def from_slug_or_fail(cls: typing.Type[T_MetaInstance], slug: str, join: bool = True) -> T_MetaInstance:
|
|
165
|
+
"""
|
|
166
|
+
Find a row by its slug, or raise an error if it doesn't exist.
|
|
167
|
+
"""
|
|
168
|
+
builder = cls.where(slug=slug)
|
|
169
|
+
if join:
|
|
170
|
+
builder = builder.join()
|
|
171
|
+
|
|
172
|
+
return builder.first_or_fail()
|
typedal/types.py
CHANGED
|
@@ -6,6 +6,7 @@ import typing
|
|
|
6
6
|
from datetime import datetime
|
|
7
7
|
from typing import Any, Optional, TypedDict
|
|
8
8
|
|
|
9
|
+
from pydal.adapters.base import BaseAdapter
|
|
9
10
|
from pydal.helpers.classes import OpRow as _OpRow
|
|
10
11
|
from pydal.helpers.classes import Reference as _Reference
|
|
11
12
|
from pydal.objects import Expression as _Expression
|
|
@@ -13,9 +14,13 @@ from pydal.objects import Field as _Field
|
|
|
13
14
|
from pydal.objects import Query as _Query
|
|
14
15
|
from pydal.objects import Rows as _Rows
|
|
15
16
|
from pydal.objects import Set as _Set
|
|
17
|
+
from pydal.objects import Table as _Table
|
|
16
18
|
from pydal.validators import Validator as _Validator
|
|
17
19
|
from typing_extensions import NotRequired
|
|
18
20
|
|
|
21
|
+
if typing.TYPE_CHECKING:
|
|
22
|
+
from .core import TypedField
|
|
23
|
+
|
|
19
24
|
AnyDict: typing.TypeAlias = dict[str, Any]
|
|
20
25
|
|
|
21
26
|
|
|
@@ -148,6 +153,62 @@ class PaginationMetadata(TypedDict):
|
|
|
148
153
|
min_max: tuple[int, int]
|
|
149
154
|
|
|
150
155
|
|
|
156
|
+
class TableProtocol(typing.Protocol): # pragma: no cover
|
|
157
|
+
"""
|
|
158
|
+
Make mypy happy.
|
|
159
|
+
"""
|
|
160
|
+
|
|
161
|
+
id: "TypedField[int]"
|
|
162
|
+
|
|
163
|
+
def __getitem__(self, item: str) -> Field:
|
|
164
|
+
"""
|
|
165
|
+
Tell mypy a Table supports dictionary notation for columns.
|
|
166
|
+
"""
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
class Table(_Table, TableProtocol): # type: ignore
|
|
170
|
+
"""
|
|
171
|
+
Make mypy happy.
|
|
172
|
+
"""
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
class CacheFn(typing.Protocol):
|
|
176
|
+
"""
|
|
177
|
+
The cache model (e.g. cache.ram) accepts these parameters (all filled by dfeault).
|
|
178
|
+
"""
|
|
179
|
+
|
|
180
|
+
def __call__(
|
|
181
|
+
self: BaseAdapter,
|
|
182
|
+
sql: str = "",
|
|
183
|
+
fields: typing.Iterable[str] = (),
|
|
184
|
+
attributes: typing.Iterable[str] = (),
|
|
185
|
+
colnames: typing.Iterable[str] = (),
|
|
186
|
+
) -> Rows:
|
|
187
|
+
"""
|
|
188
|
+
Only used for type-hinting.
|
|
189
|
+
"""
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
# CacheFn = typing.Callable[[], Rows]
|
|
193
|
+
CacheModel = typing.Callable[[str, CacheFn, int], Rows]
|
|
194
|
+
CacheTuple = tuple[CacheModel, int]
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
class SelectKwargs(typing.TypedDict, total=False):
|
|
198
|
+
"""
|
|
199
|
+
Possible keyword arguments for .select().
|
|
200
|
+
"""
|
|
201
|
+
|
|
202
|
+
join: Optional[list[Expression]]
|
|
203
|
+
left: Optional[list[Expression]]
|
|
204
|
+
orderby: Optional[Expression | str | Table]
|
|
205
|
+
limitby: Optional[tuple[int, int]]
|
|
206
|
+
distinct: bool | Field | Expression
|
|
207
|
+
orderby_on_limitby: bool
|
|
208
|
+
cacheable: bool
|
|
209
|
+
cache: CacheTuple
|
|
210
|
+
|
|
211
|
+
|
|
151
212
|
class Metadata(TypedDict):
|
|
152
213
|
"""
|
|
153
214
|
Loosely structured metadata used by Query Builder.
|
|
@@ -161,7 +222,7 @@ class Metadata(TypedDict):
|
|
|
161
222
|
|
|
162
223
|
final_query: NotRequired[Query | str | None]
|
|
163
224
|
final_args: NotRequired[list[Any]]
|
|
164
|
-
final_kwargs: NotRequired[
|
|
225
|
+
final_kwargs: NotRequired[SelectKwargs]
|
|
165
226
|
relationships: NotRequired[set[str]]
|
|
166
227
|
|
|
167
228
|
sql: NotRequired[str]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: TypeDAL
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.3.0
|
|
4
4
|
Summary: Typing support for PyDAL
|
|
5
5
|
Project-URL: Documentation, https://typedal.readthedocs.io/
|
|
6
6
|
Project-URL: Issues, https://github.com/trialandsuccess/TypeDAL/issues
|
|
@@ -35,6 +35,7 @@ Requires-Dist: mkdocs-dracula-theme; extra == 'dev'
|
|
|
35
35
|
Requires-Dist: pytest-mypy-testing; extra == 'dev'
|
|
36
36
|
Requires-Dist: python-semantic-release<8; extra == 'dev'
|
|
37
37
|
Requires-Dist: su6[all]; extra == 'dev'
|
|
38
|
+
Requires-Dist: testcontainers; extra == 'dev'
|
|
38
39
|
Requires-Dist: types-pyyaml; extra == 'dev'
|
|
39
40
|
Requires-Dist: types-tabulate; extra == 'dev'
|
|
40
41
|
Provides-Extra: migrations
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
typedal/__about__.py,sha256=3-Xok9ZOvvrfDNbH5xUjdw3tCd6M_cLiUWxppT-gDuk,206
|
|
2
|
+
typedal/__init__.py,sha256=QQpLiVl9w9hm2LBxey49Y_tCF_VB2bScVaS_mCjYy54,366
|
|
3
|
+
typedal/caching.py,sha256=SMcJsahLlZ79yykWCveERFx1ZJUNEKhA9SPmCTIuLp8,11798
|
|
4
|
+
typedal/cli.py,sha256=BXXu1w9WRRK9GA82xh_JLvvfpNDFWICXKCAWNg4a3-Y,18180
|
|
5
|
+
typedal/config.py,sha256=0qy1zrTUdtmXPM9jHzFnSR1DJsqGJqcdG6pvhzKQHe0,11625
|
|
6
|
+
typedal/core.py,sha256=Wa6Vu7ppD278tIPAl4eW8rHZRXYETM1rI3-raJ4_8GE,96148
|
|
7
|
+
typedal/fields.py,sha256=z2PD9vLWqBR_zXtiY0DthqTG4AeF3yxKoeuVfGXnSdg,5197
|
|
8
|
+
typedal/for_py4web.py,sha256=d07b8hL_PvNDUS26Z5fDH2OxWb-IETBuAFPSzrRwm04,1285
|
|
9
|
+
typedal/for_web2py.py,sha256=4RHgzGXgKIO_BYB-7adC5e35u52rX-p1t4tPEz-NK24,1867
|
|
10
|
+
typedal/helpers.py,sha256=mtRYPFlS0dx2wK8kYSJ4vm1wsTXRkdPumFRlOAjF_xU,7177
|
|
11
|
+
typedal/mixins.py,sha256=OHhVYLBGTzPSJKgp1uovBs1Y6NJa0d-DxHTOk9LyOXA,5414
|
|
12
|
+
typedal/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
13
|
+
typedal/types.py,sha256=AsUHrAXk058zmdqDbZlpf6sE85ID1Q2vofsGgCXni1s,4851
|
|
14
|
+
typedal/web2py_py4web_shared.py,sha256=VK9T8P5UwVLvfNBsY4q79ANcABv-jX76YKADt1Zz_co,1539
|
|
15
|
+
typedal/serializers/as_json.py,sha256=ffo152W-sARYXym4BzwX709rrO2-QwKk2KunWY8RNl4,2229
|
|
16
|
+
typedal-3.3.0.dist-info/METADATA,sha256=IiO1uKvVp-xZHz_9xeAyizZVAA-WQlAuPhmOxRRVp7E,9316
|
|
17
|
+
typedal-3.3.0.dist-info/WHEEL,sha256=KGYbc1zXlYddvwxnNty23BeaKzh7YuoSIvIMO4jEhvw,87
|
|
18
|
+
typedal-3.3.0.dist-info/entry_points.txt,sha256=m1wqcc_10rHWPdlQ71zEkmJDADUAnZtn7Jac_6mbyUc,44
|
|
19
|
+
typedal-3.3.0.dist-info/RECORD,,
|
typedal-3.1.4.dist-info/RECORD
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
typedal/__about__.py,sha256=rg1ktSg7m5s-wVEyJZGLexDBUkbBQvnRft88RSv-4tY,206
|
|
2
|
-
typedal/__init__.py,sha256=QQpLiVl9w9hm2LBxey49Y_tCF_VB2bScVaS_mCjYy54,366
|
|
3
|
-
typedal/caching.py,sha256=8UABVAhOlBpL96ykmqhxLaFYOe-XeAh7JoGh57OkxP8,11818
|
|
4
|
-
typedal/cli.py,sha256=3tge8B-YjgjMC6425-RMczmWvpOTfWV5QYPXRY23IWA,18200
|
|
5
|
-
typedal/config.py,sha256=jS1K0_1F5rwJtvwTZ-qR29ZCX7WlyORGEIFvfSnusko,11645
|
|
6
|
-
typedal/core.py,sha256=tocfC9KDnuOoPgUTpBhFo2WGTupS5Y0esyFSTcANwLc,95866
|
|
7
|
-
typedal/fields.py,sha256=z2PD9vLWqBR_zXtiY0DthqTG4AeF3yxKoeuVfGXnSdg,5197
|
|
8
|
-
typedal/for_py4web.py,sha256=d07b8hL_PvNDUS26Z5fDH2OxWb-IETBuAFPSzrRwm04,1285
|
|
9
|
-
typedal/for_web2py.py,sha256=4RHgzGXgKIO_BYB-7adC5e35u52rX-p1t4tPEz-NK24,1867
|
|
10
|
-
typedal/helpers.py,sha256=mtRYPFlS0dx2wK8kYSJ4vm1wsTXRkdPumFRlOAjF_xU,7177
|
|
11
|
-
typedal/mixins.py,sha256=UzuTgrJF30cowpKTHI4Y4iSub9wJoxo88XmrWHRrtGs,4361
|
|
12
|
-
typedal/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
13
|
-
typedal/types.py,sha256=1kGkNX6vfGg6ln84AG558C4Zx5ACRz-emrUTnuy-rRY,3410
|
|
14
|
-
typedal/web2py_py4web_shared.py,sha256=VK9T8P5UwVLvfNBsY4q79ANcABv-jX76YKADt1Zz_co,1539
|
|
15
|
-
typedal/serializers/as_json.py,sha256=ffo152W-sARYXym4BzwX709rrO2-QwKk2KunWY8RNl4,2229
|
|
16
|
-
typedal-3.1.4.dist-info/METADATA,sha256=yh1PzCqEG-XLvhPRLgD33O6fW-GAspkIKobbj7qNA5I,9270
|
|
17
|
-
typedal-3.1.4.dist-info/WHEEL,sha256=KGYbc1zXlYddvwxnNty23BeaKzh7YuoSIvIMO4jEhvw,87
|
|
18
|
-
typedal-3.1.4.dist-info/entry_points.txt,sha256=m1wqcc_10rHWPdlQ71zEkmJDADUAnZtn7Jac_6mbyUc,44
|
|
19
|
-
typedal-3.1.4.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|