TypeDAL 4.6.0__tar.gz → 4.6.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-4.6.0 → typedal-4.6.2}/.crush/crush.db-shm +0 -0
- typedal-4.6.2/.crush/crush.db-wal +0 -0
- {typedal-4.6.0 → typedal-4.6.2}/CHANGELOG.md +12 -0
- {typedal-4.6.0 → typedal-4.6.2}/PKG-INFO +1 -1
- {typedal-4.6.0 → typedal-4.6.2}/docs/8_mixins.md +8 -1
- {typedal-4.6.0 → typedal-4.6.2}/pyproject.toml +8 -1
- {typedal-4.6.0 → typedal-4.6.2}/src/typedal/__about__.py +1 -1
- {typedal-4.6.0 → typedal-4.6.2}/src/typedal/caching.py +2 -0
- {typedal-4.6.0 → typedal-4.6.2}/src/typedal/core.py +4 -1
- {typedal-4.6.0 → typedal-4.6.2}/src/typedal/mixins.py +34 -14
- {typedal-4.6.0 → typedal-4.6.2}/src/typedal/rows.py +2 -2
- {typedal-4.6.0 → typedal-4.6.2}/src/typedal/types.py +3 -1
- {typedal-4.6.0 → typedal-4.6.2}/tests/test_mixins.py +63 -0
- typedal-4.6.0/.crush/crush.db-wal +0 -0
- {typedal-4.6.0 → typedal-4.6.2}/.crush/.gitignore +0 -0
- {typedal-4.6.0 → typedal-4.6.2}/.crush/init +0 -0
- {typedal-4.6.0 → typedal-4.6.2}/.crush/logs/crush.log +0 -0
- {typedal-4.6.0 → typedal-4.6.2}/.github/workflows/su6.yml +0 -0
- {typedal-4.6.0 → typedal-4.6.2}/.gitignore +0 -0
- {typedal-4.6.0 → typedal-4.6.2}/.readthedocs.yml +0 -0
- {typedal-4.6.0 → typedal-4.6.2}/README.md +0 -0
- {typedal-4.6.0 → typedal-4.6.2}/coverage.svg +0 -0
- {typedal-4.6.0 → typedal-4.6.2}/docs/10_advanced_apis.md +0 -0
- {typedal-4.6.0 → typedal-4.6.2}/docs/1_getting_started.md +0 -0
- {typedal-4.6.0 → typedal-4.6.2}/docs/2_defining_tables.md +0 -0
- {typedal-4.6.0 → typedal-4.6.2}/docs/3_building_queries.md +0 -0
- {typedal-4.6.0 → typedal-4.6.2}/docs/4_relationships.md +0 -0
- {typedal-4.6.0 → typedal-4.6.2}/docs/5_py4web.md +0 -0
- {typedal-4.6.0 → typedal-4.6.2}/docs/6_migrations.md +0 -0
- {typedal-4.6.0 → typedal-4.6.2}/docs/7_configuration.md +0 -0
- {typedal-4.6.0 → typedal-4.6.2}/docs/9_memoization.md +0 -0
- {typedal-4.6.0 → typedal-4.6.2}/docs/css/code_blocks.css +0 -0
- {typedal-4.6.0 → typedal-4.6.2}/docs/index.md +0 -0
- {typedal-4.6.0 → typedal-4.6.2}/docs/requirements.txt +0 -0
- {typedal-4.6.0 → typedal-4.6.2}/example_new.py +0 -0
- {typedal-4.6.0 → typedal-4.6.2}/example_old.py +0 -0
- {typedal-4.6.0 → typedal-4.6.2}/mkdocs.yml +0 -0
- {typedal-4.6.0 → typedal-4.6.2}/src/typedal/__init__.py +0 -0
- {typedal-4.6.0 → typedal-4.6.2}/src/typedal/cli.py +0 -0
- {typedal-4.6.0 → typedal-4.6.2}/src/typedal/config.py +0 -0
- {typedal-4.6.0 → typedal-4.6.2}/src/typedal/constants.py +0 -0
- {typedal-4.6.0 → typedal-4.6.2}/src/typedal/define.py +0 -0
- {typedal-4.6.0 → typedal-4.6.2}/src/typedal/fields.py +0 -0
- {typedal-4.6.0 → typedal-4.6.2}/src/typedal/for_py4web.py +0 -0
- {typedal-4.6.0 → typedal-4.6.2}/src/typedal/for_web2py.py +0 -0
- {typedal-4.6.0 → typedal-4.6.2}/src/typedal/helpers.py +0 -0
- {typedal-4.6.0 → typedal-4.6.2}/src/typedal/py.typed +0 -0
- {typedal-4.6.0 → typedal-4.6.2}/src/typedal/query_builder.py +0 -0
- {typedal-4.6.0 → typedal-4.6.2}/src/typedal/relationships.py +0 -0
- {typedal-4.6.0 → typedal-4.6.2}/src/typedal/serializers/as_json.py +0 -0
- {typedal-4.6.0 → typedal-4.6.2}/src/typedal/tables.py +0 -0
- {typedal-4.6.0 → typedal-4.6.2}/src/typedal/web2py_py4web_shared.py +0 -0
- {typedal-4.6.0 → typedal-4.6.2}/tasks.py +0 -0
- {typedal-4.6.0 → typedal-4.6.2}/tests/__init__.py +0 -0
- {typedal-4.6.0 → typedal-4.6.2}/tests/configs/simple.toml +0 -0
- {typedal-4.6.0 → typedal-4.6.2}/tests/configs/valid.env +0 -0
- {typedal-4.6.0 → typedal-4.6.2}/tests/configs/valid.toml +0 -0
- {typedal-4.6.0 → typedal-4.6.2}/tests/py314_tests.py +0 -0
- {typedal-4.6.0 → typedal-4.6.2}/tests/test_cli.py +0 -0
- {typedal-4.6.0 → typedal-4.6.2}/tests/test_config.py +0 -0
- {typedal-4.6.0 → typedal-4.6.2}/tests/test_docs_examples.py +0 -0
- {typedal-4.6.0 → typedal-4.6.2}/tests/test_helpers.py +0 -0
- {typedal-4.6.0 → typedal-4.6.2}/tests/test_json.py +0 -0
- {typedal-4.6.0 → typedal-4.6.2}/tests/test_main.py +0 -0
- {typedal-4.6.0 → typedal-4.6.2}/tests/test_mypy.py +0 -0
- {typedal-4.6.0 → typedal-4.6.2}/tests/test_orm.py +0 -0
- {typedal-4.6.0 → typedal-4.6.2}/tests/test_py4web.py +0 -0
- {typedal-4.6.0 → typedal-4.6.2}/tests/test_query_builder.py +0 -0
- {typedal-4.6.0 → typedal-4.6.2}/tests/test_relationships.py +0 -0
- {typedal-4.6.0 → typedal-4.6.2}/tests/test_row.py +0 -0
- {typedal-4.6.0 → typedal-4.6.2}/tests/test_stats.py +0 -0
- {typedal-4.6.0 → typedal-4.6.2}/tests/test_table.py +0 -0
- {typedal-4.6.0 → typedal-4.6.2}/tests/test_web2py.py +0 -0
- {typedal-4.6.0 → typedal-4.6.2}/tests/test_xx_others.py +0 -0
- {typedal-4.6.0 → typedal-4.6.2}/tests/timings.py +0 -0
|
Binary file
|
|
Binary file
|
|
@@ -2,6 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
<!--next-version-placeholder-->
|
|
4
4
|
|
|
5
|
+
## v4.6.2 (2026-03-13)
|
|
6
|
+
|
|
7
|
+
### Fix
|
|
8
|
+
|
|
9
|
+
* Move pydantic visibility/lazy-load filtering into schema-converter path used by FastAPI ([`63c2e2c`](https://github.com/trialandsuccess/TypeDAL/commit/63c2e2c2e3c78f8aa817911dd269f650f5ba3d7d))
|
|
10
|
+
|
|
11
|
+
## v4.6.1 (2026-03-13)
|
|
12
|
+
|
|
13
|
+
### Fix
|
|
14
|
+
|
|
15
|
+
* **pydantic:** Exclude fields with 'readable=False' similar to pydal/py4web/web2py behavior ([`e47cc44`](https://github.com/trialandsuccess/TypeDAL/commit/e47cc442aa7736ba1177bc32a7dc6de58c2551aa))
|
|
16
|
+
|
|
5
17
|
## v4.6.0 (2026-03-13)
|
|
6
18
|
|
|
7
19
|
### Documentation
|
|
@@ -56,7 +56,7 @@ or use them with `pydantic.TypeAdapter`.
|
|
|
56
56
|
Add the mixin to enable `model_dump()` for serialization, including support for relationships and computed properties:
|
|
57
57
|
|
|
58
58
|
```python
|
|
59
|
-
from typedal import TypedTable
|
|
59
|
+
from typedal import TypedField, TypedTable
|
|
60
60
|
from typedal.mixins import PydanticMixin
|
|
61
61
|
|
|
62
62
|
|
|
@@ -67,6 +67,7 @@ class Author(TypedTable, PydanticMixin):
|
|
|
67
67
|
class Book(TypedTable, PydanticMixin):
|
|
68
68
|
title: str
|
|
69
69
|
author: Author
|
|
70
|
+
private_notes = TypedField(str, readable=False)
|
|
70
71
|
|
|
71
72
|
@property
|
|
72
73
|
def display_title(self) -> str:
|
|
@@ -79,6 +80,12 @@ book = Book.where(id=1).join("author").first()
|
|
|
79
80
|
# model_dump() serializes the full object graph
|
|
80
81
|
data = book.model_dump()
|
|
81
82
|
# -> {"id": 1, "title": "...", "author": {"id": 1, "name": "..."}, "display_title": "..."}
|
|
83
|
+
# (private_notes is omitted because readable=False)
|
|
84
|
+
|
|
85
|
+
# Runtime readability flags are also respected by model_dump()
|
|
86
|
+
Book.title.readable = False
|
|
87
|
+
data = book.model_dump()
|
|
88
|
+
# -> {"id": 1, "author": {"id": 1, "name": "..."}, "display_title": "..."}
|
|
82
89
|
|
|
83
90
|
# Use mode="json" for JSON-serializable output (dates as ISO strings, etc.)
|
|
84
91
|
data = book.model_dump(mode="json")
|
|
@@ -183,6 +183,7 @@ select = [
|
|
|
183
183
|
# "COM", # comma's - NO: annoying
|
|
184
184
|
# "PTH", # use pathlib - NO: annoying
|
|
185
185
|
"RUF", # ruff rules
|
|
186
|
+
# "D", # docs
|
|
186
187
|
]
|
|
187
188
|
unfixable = [
|
|
188
189
|
# Don't touch unused imports
|
|
@@ -191,13 +192,19 @@ unfixable = [
|
|
|
191
192
|
extend-ignore = [
|
|
192
193
|
# db.field == None should NOT be fixed to db.field is None
|
|
193
194
|
"E711",
|
|
195
|
+
"D200",
|
|
196
|
+
"D212",
|
|
197
|
+
"D418",
|
|
194
198
|
]
|
|
195
199
|
|
|
196
|
-
|
|
197
200
|
ignore = [
|
|
198
201
|
"RUF013" # implicit optional
|
|
199
202
|
]
|
|
200
203
|
|
|
204
|
+
|
|
205
|
+
[tool.ruff.lint.pydocstyle]
|
|
206
|
+
convention = "google"
|
|
207
|
+
|
|
201
208
|
[tool.bandit]
|
|
202
209
|
# bandit -c pyproject.toml -r .
|
|
203
210
|
exclude_dirs = [".bak", "venv"]
|
|
@@ -203,6 +203,7 @@ def _remove_cache(s: Set, tablename: str) -> None:
|
|
|
203
203
|
indeces = s.select("id").column("id")
|
|
204
204
|
remove_cache(indeces, tablename)
|
|
205
205
|
|
|
206
|
+
|
|
206
207
|
def get_expire(
|
|
207
208
|
expires_at: t.Optional[dt.datetime] = None,
|
|
208
209
|
ttl: t.Optional[int | dt.timedelta] = None,
|
|
@@ -419,6 +420,7 @@ class Stats[T](t.TypedDict):
|
|
|
419
420
|
valid: T
|
|
420
421
|
expired: T
|
|
421
422
|
|
|
423
|
+
|
|
422
424
|
RowStats = t.TypedDict(
|
|
423
425
|
"RowStats",
|
|
424
426
|
{
|
|
@@ -4,6 +4,7 @@ Core functionality of TypeDAL.
|
|
|
4
4
|
|
|
5
5
|
from __future__ import annotations
|
|
6
6
|
|
|
7
|
+
# noinspection PyUnusedImports
|
|
7
8
|
import datetime as dt
|
|
8
9
|
import sys
|
|
9
10
|
import typing as t
|
|
@@ -21,7 +22,9 @@ from .helpers import (
|
|
|
21
22
|
sql_expression,
|
|
22
23
|
to_snake,
|
|
23
24
|
)
|
|
24
|
-
|
|
25
|
+
|
|
26
|
+
# noinspection PyUnusedImports
|
|
27
|
+
from .types import CacheStatus, Field, Template
|
|
25
28
|
|
|
26
29
|
try:
|
|
27
30
|
# python 3.14+
|
|
@@ -376,6 +376,12 @@ class PydanticMixin(Mixin):
|
|
|
376
376
|
field_name: cls._unwrap_pydantic_field_type(field_type) for field_name, field_type in annotations.items()
|
|
377
377
|
}
|
|
378
378
|
|
|
379
|
+
# Respect pyDAL visibility: unreadable DB fields should not be part of pydantic output/schema.
|
|
380
|
+
for field_name in list(fields):
|
|
381
|
+
model_attr = full_dict.get(field_name, getattr(cls, field_name, None))
|
|
382
|
+
if hasattr(model_attr, "readable") and not getattr(model_attr, "readable"):
|
|
383
|
+
fields.pop(field_name, None)
|
|
384
|
+
|
|
379
385
|
for field_name, field_type in fields.items():
|
|
380
386
|
cls._ensure_pydantic_compatible_type(field_name, field_type)
|
|
381
387
|
|
|
@@ -420,8 +426,9 @@ class PydanticMixin(Mixin):
|
|
|
420
426
|
)
|
|
421
427
|
|
|
422
428
|
@staticmethod
|
|
423
|
-
def _make_instance_converter(
|
|
429
|
+
def _make_instance_converter(model_cls: type, fields: dict[str, t.Any]) -> t.Callable[[t.Any], t.Any]:
|
|
424
430
|
_PRIMITIVES = (str, float, bool, bytes)
|
|
431
|
+
relationship_names = set(model_cls.get_relationships()) if hasattr(model_cls, "get_relationships") else set()
|
|
425
432
|
|
|
426
433
|
def convert(value: t.Any) -> t.Any:
|
|
427
434
|
if isinstance(value, dict):
|
|
@@ -432,7 +439,16 @@ class PydanticMixin(Mixin):
|
|
|
432
439
|
if isinstance(value, _PRIMITIVES) or value is None:
|
|
433
440
|
return value
|
|
434
441
|
# Handles both TypedTable instances and raw pydal Row objects
|
|
435
|
-
|
|
442
|
+
values_dict = getattr(value, "__dict__", {})
|
|
443
|
+
result: dict[str, t.Any] = {}
|
|
444
|
+
for field_name in fields:
|
|
445
|
+
# Never trigger lazy-loads during pydantic conversion.
|
|
446
|
+
if field_name in relationship_names and field_name not in values_dict:
|
|
447
|
+
continue
|
|
448
|
+
|
|
449
|
+
result[field_name] = getattr(value, field_name, None)
|
|
450
|
+
|
|
451
|
+
return result
|
|
436
452
|
|
|
437
453
|
return convert
|
|
438
454
|
|
|
@@ -529,11 +545,9 @@ class PydanticMixin(Mixin):
|
|
|
529
545
|
if field_name in _required_fields:
|
|
530
546
|
# Always computed — keep required and non-nullable for clean TS types
|
|
531
547
|
return core_schema.typed_dict_field(inner, required=True)
|
|
532
|
-
# DB fields / relationships: TypeDAL can return partial rows, so allow None
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
required=False,
|
|
536
|
-
)
|
|
548
|
+
# DB fields / relationships: TypeDAL can return partial rows, so allow None when present,
|
|
549
|
+
# but keep missing fields absent (don't auto-fill null/default values).
|
|
550
|
+
return core_schema.typed_dict_field(core_schema.nullable_schema(inner), required=False)
|
|
537
551
|
|
|
538
552
|
schema_fields = {field_name: make_field(field_name, field_type) for field_name, field_type in fields.items()}
|
|
539
553
|
|
|
@@ -585,13 +599,19 @@ class PydanticMixin(Mixin):
|
|
|
585
599
|
|
|
586
600
|
def model_dump(self, mode: str = "python", *, _shallow: bool = False) -> dict[str, t.Any]:
|
|
587
601
|
"""Serialize this model to a dict, with optional shallow nested output."""
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
602
|
+
cls = type(self)
|
|
603
|
+
relationship_names = set(cls.get_relationships())
|
|
604
|
+
data: dict[str, t.Any] = {}
|
|
605
|
+
for field_name in self._pydantic_fields(
|
|
606
|
+
include_relationships=not _shallow,
|
|
607
|
+
include_properties=not _shallow,
|
|
608
|
+
):
|
|
609
|
+
# Only include relationship data that was already selected/joined.
|
|
610
|
+
# This prevents model_dump from triggering lazy-loading queries.
|
|
611
|
+
if field_name in relationship_names and field_name not in self.__dict__:
|
|
612
|
+
continue
|
|
613
|
+
|
|
614
|
+
data[field_name] = getattr(self, field_name, None)
|
|
595
615
|
|
|
596
616
|
if mode == "json":
|
|
597
617
|
return dump_pydantic(data, _shallow_nested=True)
|
|
@@ -421,8 +421,8 @@ class TypedRows(t.Collection[T_MetaInstance], Rows):
|
|
|
421
421
|
fields: list[Field] | None = None,
|
|
422
422
|
) -> t.Generator[T_MetaInstance, None, None] | T_MetaInstance:
|
|
423
423
|
"""
|
|
424
|
-
Takes an index and returns a copy of the indexed row with values
|
|
425
|
-
|
|
424
|
+
Takes an index and returns a copy of the indexed row with values
|
|
425
|
+
transformed via the "represent" attributes of the associated fields.
|
|
426
426
|
|
|
427
427
|
Args:
|
|
428
428
|
i: index. If not specified, a generator is returned for iteration
|
|
@@ -35,7 +35,9 @@ except ImportError:
|
|
|
35
35
|
# Internal references
|
|
36
36
|
if t.TYPE_CHECKING:
|
|
37
37
|
from .fields import TypedField
|
|
38
|
-
|
|
38
|
+
|
|
39
|
+
# noinspection PyUnusedImports
|
|
40
|
+
from .tables import TypedTable, _TypedTable
|
|
39
41
|
|
|
40
42
|
# ---------------------------------------------------------------------------
|
|
41
43
|
# Aliases
|
|
@@ -232,6 +232,16 @@ class PydanticTupleAndLiteralSchema(TypedTable, PydanticMixin):
|
|
|
232
232
|
status: typing.Literal["draft", "published"]
|
|
233
233
|
|
|
234
234
|
|
|
235
|
+
class PydanticHiddenTypedField(TypedTable, PydanticMixin):
|
|
236
|
+
visible = TypedField(str)
|
|
237
|
+
hidden = TypedField(str, readable=False)
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
class PydanticHiddenRelationshipHost(TypedTable, PydanticMixin):
|
|
241
|
+
name: str
|
|
242
|
+
with_hidden = relationship(list[PydanticHiddenTypedField], lambda self, other: self.id == other.id, lazy="allow")
|
|
243
|
+
|
|
244
|
+
|
|
235
245
|
@pytest.fixture
|
|
236
246
|
def pydantic_db():
|
|
237
247
|
db = TypeDAL("sqlite:memory")
|
|
@@ -241,6 +251,8 @@ def pydantic_db():
|
|
|
241
251
|
db.define(PydanticStringRelationship)
|
|
242
252
|
db.define(PydanticGenericResolvedRelationship)
|
|
243
253
|
db.define(PydanticGenericUnresolvedRelationship)
|
|
254
|
+
db.define(PydanticHiddenTypedField)
|
|
255
|
+
db.define(PydanticHiddenRelationshipHost)
|
|
244
256
|
db.define(NonPydanticAuthor)
|
|
245
257
|
yield db
|
|
246
258
|
|
|
@@ -443,6 +455,57 @@ def test_pydantic_fields_include_typedfield_and_skip_no_getter_property(pydantic
|
|
|
443
455
|
assert "empty_prop" not in property_fields
|
|
444
456
|
|
|
445
457
|
|
|
458
|
+
def test_pydantic_skips_unreadable_typedfield_in_model_dump(pydantic_db):
|
|
459
|
+
row = PydanticHiddenTypedField.insert(visible="show", hidden="hide")
|
|
460
|
+
data = row.model_dump()
|
|
461
|
+
assert data == {"id": row.id, "visible": "show"}
|
|
462
|
+
|
|
463
|
+
PydanticHiddenTypedField.visible.readable = False
|
|
464
|
+
row = PydanticHiddenTypedField.insert(visible="show-2", hidden="hide-2")
|
|
465
|
+
data = row.model_dump()
|
|
466
|
+
assert data == {"id": row.id}
|
|
467
|
+
|
|
468
|
+
|
|
469
|
+
def test_pydantic_skips_unreadable_typedfield_in_nested_list_relationship_dump(pydantic_db):
|
|
470
|
+
hidden = PydanticHiddenTypedField.insert(visible="show", hidden="hide")
|
|
471
|
+
host = PydanticHiddenRelationshipHost.insert(name="Host")
|
|
472
|
+
assert hidden.id == host.id
|
|
473
|
+
|
|
474
|
+
joined = PydanticHiddenRelationshipHost.where(id=host.id).join("with_hidden").first()
|
|
475
|
+
assert joined is not None
|
|
476
|
+
|
|
477
|
+
data = joined.model_dump(mode="json")
|
|
478
|
+
assert data["with_hidden"] == [{"id": hidden.id, "visible": "show"}]
|
|
479
|
+
assert joined.with_hidden[0].hidden == "hide"
|
|
480
|
+
assert [item.model_dump() for item in joined.with_hidden] == [{"id": hidden.id, "visible": "show"}]
|
|
481
|
+
|
|
482
|
+
|
|
483
|
+
def test_pydantic_model_dump_never_lazy_loads_unjoined_relationships(pydantic_db):
|
|
484
|
+
hidden = PydanticHiddenTypedField.insert(visible="show", hidden="hide")
|
|
485
|
+
host = PydanticHiddenRelationshipHost.insert(name="Host")
|
|
486
|
+
assert hidden.id == host.id
|
|
487
|
+
|
|
488
|
+
data = host.model_dump(mode="json")
|
|
489
|
+
assert "with_hidden" not in data
|
|
490
|
+
|
|
491
|
+
|
|
492
|
+
def test_pydantic_type_adapter_skips_unreadable_fields(pydantic_db):
|
|
493
|
+
row = PydanticHiddenTypedField.insert(visible="show", hidden="hide")
|
|
494
|
+
ta = pydantic.TypeAdapter(PydanticHiddenTypedField)
|
|
495
|
+
data = ta.validate_python(row)
|
|
496
|
+
assert data == {"id": row.id, "visible": "show"}
|
|
497
|
+
|
|
498
|
+
|
|
499
|
+
def test_pydantic_type_adapter_never_lazy_loads_unjoined_relationships(pydantic_db):
|
|
500
|
+
hidden = PydanticHiddenTypedField.insert(visible="show", hidden="hide")
|
|
501
|
+
host = PydanticHiddenRelationshipHost.insert(name="Host")
|
|
502
|
+
assert hidden.id == host.id
|
|
503
|
+
|
|
504
|
+
ta = pydantic.TypeAdapter(PydanticHiddenRelationshipHost)
|
|
505
|
+
data = ta.validate_python(host)
|
|
506
|
+
assert "with_hidden" not in data
|
|
507
|
+
|
|
508
|
+
|
|
446
509
|
def test_pydantic_compatibility_non_type_and_missing_relationship_type():
|
|
447
510
|
# ForwardRef is not a runtime type; this should be a no-op, not a crash.
|
|
448
511
|
PydanticMixin._ensure_pydantic_compatible_type("x", typing.ForwardRef("Anything"))
|
|
Binary file
|
|
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
|
|
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
|
|
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
|