TypeDAL 3.8.0__py3-none-any.whl → 3.8.2__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/core.py +15 -6
- typedal/for_web2py.py +2 -0
- typedal/mixins.py +17 -6
- typedal/types.py +1 -1
- {typedal-3.8.0.dist-info → typedal-3.8.2.dist-info}/METADATA +1 -1
- {typedal-3.8.0.dist-info → typedal-3.8.2.dist-info}/RECORD +9 -9
- {typedal-3.8.0.dist-info → typedal-3.8.2.dist-info}/WHEEL +0 -0
- {typedal-3.8.0.dist-info → typedal-3.8.2.dist-info}/entry_points.txt +0 -0
typedal/__about__.py
CHANGED
typedal/core.py
CHANGED
|
@@ -279,9 +279,10 @@ def relationship(_type: To_Type, condition: Condition = None, join: JOIN_OPTIONS
|
|
|
279
279
|
)
|
|
280
280
|
|
|
281
281
|
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
282
|
+
T_Field: typing.TypeAlias = typing.Union["TypedField[Any]", "Table", Type["TypedTable"]]
|
|
283
|
+
|
|
284
|
+
|
|
285
|
+
def _generate_relationship_condition(_: Type["TypedTable"], key: str, field: T_Field) -> Condition:
|
|
285
286
|
origin = typing.get_origin(field)
|
|
286
287
|
# else: generic
|
|
287
288
|
|
|
@@ -299,7 +300,7 @@ def _generate_relationship_condition(
|
|
|
299
300
|
def to_relationship(
|
|
300
301
|
cls: Type["TypedTable"] | type[Any],
|
|
301
302
|
key: str,
|
|
302
|
-
field:
|
|
303
|
+
field: T_Field,
|
|
303
304
|
) -> typing.Optional[Relationship[Any]]:
|
|
304
305
|
"""
|
|
305
306
|
Used to automatically create relationship instance for reference fields.
|
|
@@ -317,9 +318,14 @@ def to_relationship(
|
|
|
317
318
|
Also works for list:reference (list[OtherTable]) and TypedField[OtherTable].
|
|
318
319
|
"""
|
|
319
320
|
if looks_like(field, TypedField):
|
|
321
|
+
# typing.get_args works for list[str] but not for TypedField[role] :(
|
|
320
322
|
if args := typing.get_args(field):
|
|
323
|
+
# TypedField[SomeType] -> SomeType
|
|
321
324
|
field = args[0]
|
|
322
|
-
|
|
325
|
+
elif hasattr(field, "_type"):
|
|
326
|
+
# TypedField(SomeType) -> SomeType
|
|
327
|
+
field = typing.cast(T_Field, field._type)
|
|
328
|
+
else: # pragma: no cover
|
|
323
329
|
# weird
|
|
324
330
|
return None
|
|
325
331
|
|
|
@@ -543,13 +549,16 @@ class TypeDAL(pydal.DAL): # type: ignore
|
|
|
543
549
|
]
|
|
544
550
|
|
|
545
551
|
# add implicit relationships:
|
|
546
|
-
# User; list[User]; TypedField[User]; TypedField[list[User]]
|
|
552
|
+
# User; list[User]; TypedField[User]; TypedField[list[User]]; TypedField(User); TypedField(list[User])
|
|
547
553
|
relationships |= {
|
|
548
554
|
k: new_relationship
|
|
549
555
|
for k in reference_field_keys
|
|
550
556
|
if k not in relationships and (new_relationship := to_relationship(cls, k, annotations[k]))
|
|
551
557
|
}
|
|
552
558
|
|
|
559
|
+
# fixme: list[Reference] is recognized as relationship,
|
|
560
|
+
# TypedField(list[Reference]) is NOT recognized!!!
|
|
561
|
+
|
|
553
562
|
cache_dependency = self._config.caching and kwargs.pop("cache_dependency", True)
|
|
554
563
|
|
|
555
564
|
table: Table = self.define_table(tablename, *fields.values(), **kwargs)
|
typedal/for_web2py.py
CHANGED
typedal/mixins.py
CHANGED
|
@@ -36,6 +36,14 @@ class Mixin(_TypedTable):
|
|
|
36
36
|
('inconsistent method resolution' or 'metaclass conflicts')
|
|
37
37
|
"""
|
|
38
38
|
|
|
39
|
+
__settings__: typing.ClassVar[dict[str, Any]]
|
|
40
|
+
|
|
41
|
+
def __init_subclass__(cls, **kwargs: Any):
|
|
42
|
+
"""
|
|
43
|
+
Ensures __settings__ exists for other mixins.
|
|
44
|
+
"""
|
|
45
|
+
cls.__settings__ = getattr(cls, "__settings__", None) or {}
|
|
46
|
+
|
|
39
47
|
|
|
40
48
|
class TimestampsMixin(Mixin):
|
|
41
49
|
"""
|
|
@@ -102,12 +110,16 @@ class SlugMixin(Mixin):
|
|
|
102
110
|
},
|
|
103
111
|
) # set via init subclass
|
|
104
112
|
|
|
105
|
-
def __init_subclass__(
|
|
113
|
+
def __init_subclass__(
|
|
114
|
+
cls, slug_field: str = None, slug_suffix_length: int = 0, slug_suffix: Optional[int] = None, **kw: Any
|
|
115
|
+
) -> None:
|
|
106
116
|
"""
|
|
107
117
|
Bind 'slug field' option to be used later (on_define).
|
|
108
118
|
|
|
109
119
|
You can control the length of the random suffix with the `slug_suffix_length` option (0 is no suffix).
|
|
110
120
|
"""
|
|
121
|
+
super().__init_subclass__(**kw)
|
|
122
|
+
|
|
111
123
|
# unfortunately, PyCharm and mypy do not recognize/autocomplete/typecheck init subclass (keyword) arguments.
|
|
112
124
|
if slug_field is None:
|
|
113
125
|
raise ValueError(
|
|
@@ -115,7 +127,7 @@ class SlugMixin(Mixin):
|
|
|
115
127
|
"e.g. `class MyClass(TypedTable, SlugMixin, slug_field='title'): ...`"
|
|
116
128
|
)
|
|
117
129
|
|
|
118
|
-
if
|
|
130
|
+
if slug_suffix:
|
|
119
131
|
warnings.warn(
|
|
120
132
|
"The 'slug_suffix' option is deprecated, use 'slug_suffix_length' instead.",
|
|
121
133
|
DeprecationWarning,
|
|
@@ -123,10 +135,9 @@ class SlugMixin(Mixin):
|
|
|
123
135
|
|
|
124
136
|
slug_suffix = slug_suffix_length or kw.get("slug_suffix", 0)
|
|
125
137
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
}
|
|
138
|
+
# append settings:
|
|
139
|
+
cls.__settings__["slug_field"] = slug_field
|
|
140
|
+
cls.__settings__["slug_suffix"] = slug_suffix
|
|
130
141
|
|
|
131
142
|
@classmethod
|
|
132
143
|
def __on_define__(cls, db: TypeDAL) -> None:
|
typedal/types.py
CHANGED
|
@@ -281,7 +281,7 @@ class FieldSettings(TypedDict, total=False):
|
|
|
281
281
|
length: int
|
|
282
282
|
default: Any
|
|
283
283
|
required: bool
|
|
284
|
-
requires: list[AnyCallable | Any]
|
|
284
|
+
requires: list[AnyCallable | Any | Validator] | Validator | AnyCallable
|
|
285
285
|
ondelete: str
|
|
286
286
|
onupdate: str
|
|
287
287
|
notnull: bool
|
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
typedal/__about__.py,sha256=
|
|
1
|
+
typedal/__about__.py,sha256=iu41-36uyyjXDWrYd_vxhv3fdbkaA4fF1hYPJrHMKTw,206
|
|
2
2
|
typedal/__init__.py,sha256=QQpLiVl9w9hm2LBxey49Y_tCF_VB2bScVaS_mCjYy54,366
|
|
3
3
|
typedal/caching.py,sha256=SMcJsahLlZ79yykWCveERFx1ZJUNEKhA9SPmCTIuLp8,11798
|
|
4
4
|
typedal/cli.py,sha256=wzyId6YwRyqfuJ2byxvl6YecDNaKpkLmo-R5HvRuTok,19265
|
|
5
5
|
typedal/config.py,sha256=0qy1zrTUdtmXPM9jHzFnSR1DJsqGJqcdG6pvhzKQHe0,11625
|
|
6
|
-
typedal/core.py,sha256=
|
|
6
|
+
typedal/core.py,sha256=3gIyFrnh3qLBxzwQJ9qsnXIX16ke9iAFODkt5bNuIYI,100433
|
|
7
7
|
typedal/fields.py,sha256=A4qt0aK4F_-UeOY-xJ0ObVY-tFEoLFy7TYRMHnp4g6o,6516
|
|
8
8
|
typedal/for_py4web.py,sha256=d07b8hL_PvNDUS26Z5fDH2OxWb-IETBuAFPSzrRwm04,1285
|
|
9
|
-
typedal/for_web2py.py,sha256=
|
|
9
|
+
typedal/for_web2py.py,sha256=xn7zo6ImsmTkH6LacbjLQl2oqyBvP0zLqRxEJvMQk1w,1929
|
|
10
10
|
typedal/helpers.py,sha256=uej96exzJ9qVBd6LudP8uJ_7Cmq6vKraerdKvSRBVjc,8128
|
|
11
|
-
typedal/mixins.py,sha256=
|
|
11
|
+
typedal/mixins.py,sha256=6QfeVBAk7J4uHSR82Ek_Bhq43hzxnrmLn6xqxZqYtMk,5757
|
|
12
12
|
typedal/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
13
|
-
typedal/types.py,sha256=
|
|
13
|
+
typedal/types.py,sha256=1FIgv1s0be0E8r5Wd9E1nvDvK4ETV8u2NlfI7_P6UUY,6752
|
|
14
14
|
typedal/web2py_py4web_shared.py,sha256=VK9T8P5UwVLvfNBsY4q79ANcABv-jX76YKADt1Zz_co,1539
|
|
15
15
|
typedal/serializers/as_json.py,sha256=ffo152W-sARYXym4BzwX709rrO2-QwKk2KunWY8RNl4,2229
|
|
16
|
-
typedal-3.8.
|
|
17
|
-
typedal-3.8.
|
|
18
|
-
typedal-3.8.
|
|
19
|
-
typedal-3.8.
|
|
16
|
+
typedal-3.8.2.dist-info/METADATA,sha256=YeMYoaZx1r1mHD6WZT7sFRDXUX0B2Ee0odsEVAhsl7E,10463
|
|
17
|
+
typedal-3.8.2.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
|
|
18
|
+
typedal-3.8.2.dist-info/entry_points.txt,sha256=m1wqcc_10rHWPdlQ71zEkmJDADUAnZtn7Jac_6mbyUc,44
|
|
19
|
+
typedal-3.8.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|