TypeDAL 4.9.4__tar.gz → 4.9.6__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.9.4 → typedal-4.9.6}/CHANGELOG.md +12 -0
- {typedal-4.9.4 → typedal-4.9.6}/PKG-INFO +1 -1
- {typedal-4.9.4 → typedal-4.9.6}/src/typedal/__about__.py +1 -1
- {typedal-4.9.4 → typedal-4.9.6}/src/typedal/core.py +9 -0
- {typedal-4.9.4 → typedal-4.9.6}/src/typedal/fields.py +5 -0
- {typedal-4.9.4 → typedal-4.9.6}/src/typedal/relationships.py +1 -1
- {typedal-4.9.4 → typedal-4.9.6}/src/typedal/tables.py +11 -0
- {typedal-4.9.4 → typedal-4.9.6}/tests/test_main.py +25 -0
- {typedal-4.9.4 → typedal-4.9.6}/.crush/.gitignore +0 -0
- {typedal-4.9.4 → typedal-4.9.6}/.crush/crush.db-shm +0 -0
- {typedal-4.9.4 → typedal-4.9.6}/.crush/crush.db-wal +0 -0
- {typedal-4.9.4 → typedal-4.9.6}/.crush/init +0 -0
- {typedal-4.9.4 → typedal-4.9.6}/.crush/logs/crush.log +0 -0
- {typedal-4.9.4 → typedal-4.9.6}/.github/workflows/su6.yml +0 -0
- {typedal-4.9.4 → typedal-4.9.6}/.gitignore +0 -0
- {typedal-4.9.4 → typedal-4.9.6}/.readthedocs.yml +0 -0
- {typedal-4.9.4 → typedal-4.9.6}/README.md +0 -0
- {typedal-4.9.4 → typedal-4.9.6}/coverage.svg +0 -0
- {typedal-4.9.4 → typedal-4.9.6}/docs/10_advanced_apis.md +0 -0
- {typedal-4.9.4 → typedal-4.9.6}/docs/1_getting_started.md +0 -0
- {typedal-4.9.4 → typedal-4.9.6}/docs/2_defining_tables.md +0 -0
- {typedal-4.9.4 → typedal-4.9.6}/docs/3_building_queries.md +0 -0
- {typedal-4.9.4 → typedal-4.9.6}/docs/4_relationships.md +0 -0
- {typedal-4.9.4 → typedal-4.9.6}/docs/5_py4web.md +0 -0
- {typedal-4.9.4 → typedal-4.9.6}/docs/6_migrations.md +0 -0
- {typedal-4.9.4 → typedal-4.9.6}/docs/7_configuration.md +0 -0
- {typedal-4.9.4 → typedal-4.9.6}/docs/8_mixins.md +0 -0
- {typedal-4.9.4 → typedal-4.9.6}/docs/9_memoization.md +0 -0
- {typedal-4.9.4 → typedal-4.9.6}/docs/css/code_blocks.css +0 -0
- {typedal-4.9.4 → typedal-4.9.6}/docs/index.md +0 -0
- {typedal-4.9.4 → typedal-4.9.6}/docs/requirements.txt +0 -0
- {typedal-4.9.4 → typedal-4.9.6}/example_new.py +0 -0
- {typedal-4.9.4 → typedal-4.9.6}/example_old.py +0 -0
- {typedal-4.9.4 → typedal-4.9.6}/mkdocs.yml +0 -0
- {typedal-4.9.4 → typedal-4.9.6}/pyproject.toml +0 -0
- {typedal-4.9.4 → typedal-4.9.6}/src/typedal/__init__.py +0 -0
- {typedal-4.9.4 → typedal-4.9.6}/src/typedal/caching.py +0 -0
- {typedal-4.9.4 → typedal-4.9.6}/src/typedal/cli.py +0 -0
- {typedal-4.9.4 → typedal-4.9.6}/src/typedal/config.py +0 -0
- {typedal-4.9.4 → typedal-4.9.6}/src/typedal/constants.py +0 -0
- {typedal-4.9.4 → typedal-4.9.6}/src/typedal/define.py +0 -0
- {typedal-4.9.4 → typedal-4.9.6}/src/typedal/enum_helpers.py +0 -0
- {typedal-4.9.4 → typedal-4.9.6}/src/typedal/for_py4web.py +0 -0
- {typedal-4.9.4 → typedal-4.9.6}/src/typedal/for_web2py.py +0 -0
- {typedal-4.9.4 → typedal-4.9.6}/src/typedal/helpers.py +0 -0
- {typedal-4.9.4 → typedal-4.9.6}/src/typedal/mixins.py +0 -0
- {typedal-4.9.4 → typedal-4.9.6}/src/typedal/py.typed +0 -0
- {typedal-4.9.4 → typedal-4.9.6}/src/typedal/query_builder.py +0 -0
- {typedal-4.9.4 → typedal-4.9.6}/src/typedal/rows.py +0 -0
- {typedal-4.9.4 → typedal-4.9.6}/src/typedal/serializers/as_json.py +0 -0
- {typedal-4.9.4 → typedal-4.9.6}/src/typedal/serializers/typescript.py +0 -0
- {typedal-4.9.4 → typedal-4.9.6}/src/typedal/types.py +0 -0
- {typedal-4.9.4 → typedal-4.9.6}/src/typedal/web2py_py4web_shared.py +0 -0
- {typedal-4.9.4 → typedal-4.9.6}/tasks.py +0 -0
- {typedal-4.9.4 → typedal-4.9.6}/tests/__init__.py +0 -0
- {typedal-4.9.4 → typedal-4.9.6}/tests/configs/simple.toml +0 -0
- {typedal-4.9.4 → typedal-4.9.6}/tests/configs/valid.env +0 -0
- {typedal-4.9.4 → typedal-4.9.6}/tests/configs/valid.toml +0 -0
- {typedal-4.9.4 → typedal-4.9.6}/tests/conftest.py +0 -0
- {typedal-4.9.4 → typedal-4.9.6}/tests/py314_tests.py +0 -0
- {typedal-4.9.4 → typedal-4.9.6}/tests/test_cli.py +0 -0
- {typedal-4.9.4 → typedal-4.9.6}/tests/test_config.py +0 -0
- {typedal-4.9.4 → typedal-4.9.6}/tests/test_docs_examples.py +0 -0
- {typedal-4.9.4 → typedal-4.9.6}/tests/test_helpers.py +0 -0
- {typedal-4.9.4 → typedal-4.9.6}/tests/test_json.py +0 -0
- {typedal-4.9.4 → typedal-4.9.6}/tests/test_mixins.py +0 -0
- {typedal-4.9.4 → typedal-4.9.6}/tests/test_mypy.py +0 -0
- {typedal-4.9.4 → typedal-4.9.6}/tests/test_orm.py +0 -0
- {typedal-4.9.4 → typedal-4.9.6}/tests/test_py4web.py +0 -0
- {typedal-4.9.4 → typedal-4.9.6}/tests/test_query_builder.py +0 -0
- {typedal-4.9.4 → typedal-4.9.6}/tests/test_relationships.py +0 -0
- {typedal-4.9.4 → typedal-4.9.6}/tests/test_row.py +0 -0
- {typedal-4.9.4 → typedal-4.9.6}/tests/test_stats.py +0 -0
- {typedal-4.9.4 → typedal-4.9.6}/tests/test_table.py +0 -0
- {typedal-4.9.4 → typedal-4.9.6}/tests/test_typescript.py +0 -0
- {typedal-4.9.4 → typedal-4.9.6}/tests/test_typing_mypy.md +0 -0
- {typedal-4.9.4 → typedal-4.9.6}/tests/test_typing_pyright.md +0 -0
- {typedal-4.9.4 → typedal-4.9.6}/tests/test_web2py.py +0 -0
- {typedal-4.9.4 → typedal-4.9.6}/tests/test_xx_others.py +0 -0
- {typedal-4.9.4 → typedal-4.9.6}/tests/timings.py +0 -0
|
@@ -2,6 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
<!--next-version-placeholder-->
|
|
4
4
|
|
|
5
|
+
## v4.9.6 (2026-07-14)
|
|
6
|
+
|
|
7
|
+
### Fix
|
|
8
|
+
|
|
9
|
+
* **core:** Unbind models when closing database ([`e025d0c`](https://github.com/trialandsuccess/TypeDAL/commit/e025d0c13cdb95943ad22430d9822171834c3092))
|
|
10
|
+
|
|
11
|
+
## v4.9.5 (2026-07-05)
|
|
12
|
+
|
|
13
|
+
### Fix
|
|
14
|
+
|
|
15
|
+
* Restore 3.12-support syntax-wise ([`908a5a4`](https://github.com/trialandsuccess/TypeDAL/commit/908a5a49f2a83637acba7073ef3062ab2dd84496))
|
|
16
|
+
|
|
5
17
|
## v4.9.4 (2026-07-03)
|
|
6
18
|
|
|
7
19
|
### Fix
|
|
@@ -280,6 +280,15 @@ class TypeDAL(_TypeDALBase):
|
|
|
280
280
|
self.try_define(_TypedalCache)
|
|
281
281
|
self.try_define(_TypedalCacheDependency)
|
|
282
282
|
|
|
283
|
+
def close(self) -> None:
|
|
284
|
+
"""Close the database connection and unbind all defined TypedTable models."""
|
|
285
|
+
try:
|
|
286
|
+
super().close()
|
|
287
|
+
finally:
|
|
288
|
+
for model in set(self._builder.class_map.values()):
|
|
289
|
+
model.unbind()
|
|
290
|
+
self._builder.class_map.clear()
|
|
291
|
+
|
|
283
292
|
def try_define[T: t.Any](self, model: t.Type[T], verbose: bool = False) -> t.Type[T]:
|
|
284
293
|
"""
|
|
285
294
|
Try to define a model with migrate or fall back to fake migrate.
|
|
@@ -197,6 +197,11 @@ class TypedField[T_Value](Expression): # pragma: no cover
|
|
|
197
197
|
self._table = table
|
|
198
198
|
self._field = field
|
|
199
199
|
|
|
200
|
+
def unbind(self) -> None:
|
|
201
|
+
"""Remove references to the pydal objects created during ``bind``."""
|
|
202
|
+
self._table = None
|
|
203
|
+
self._field = None
|
|
204
|
+
|
|
200
205
|
def __getattr__(self, key: str) -> t.Any:
|
|
201
206
|
"""
|
|
202
207
|
If the regular getattribute does not work, try to get info from the related Field.
|
|
@@ -121,6 +121,17 @@ class TableMeta(type):
|
|
|
121
121
|
self._relationships = relationships
|
|
122
122
|
self._permissions = merge_permissions(permissions)
|
|
123
123
|
|
|
124
|
+
def unbind(self) -> None:
|
|
125
|
+
"""Remove the database bindings created by ``db.define``."""
|
|
126
|
+
for value in self.__dict__.values():
|
|
127
|
+
if isinstance(value, TypedField):
|
|
128
|
+
value.unbind()
|
|
129
|
+
|
|
130
|
+
self._db = None
|
|
131
|
+
self._table = None
|
|
132
|
+
self._relationships = None
|
|
133
|
+
self._permissions = None
|
|
134
|
+
|
|
124
135
|
def __getattr__(self, col: str) -> t.Optional[Field]:
|
|
125
136
|
"""
|
|
126
137
|
Magic method used by TypedTableMeta to get a database field with dot notation on a class.
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import enum
|
|
2
|
+
import gc
|
|
2
3
|
import re
|
|
3
4
|
import sys
|
|
4
5
|
import typing
|
|
6
|
+
import weakref
|
|
5
7
|
from copy import copy
|
|
6
8
|
from sqlite3 import IntegrityError
|
|
7
9
|
from typing import ForwardRef
|
|
@@ -22,6 +24,29 @@ def test_about():
|
|
|
22
24
|
db = TypeDAL("sqlite:memory")
|
|
23
25
|
|
|
24
26
|
|
|
27
|
+
def test_database_is_garbage_collected_after_close():
|
|
28
|
+
db = TypeDAL("sqlite:memory", enable_typedal_caching=False)
|
|
29
|
+
|
|
30
|
+
@db.define
|
|
31
|
+
class TemporaryTable(TypedTable):
|
|
32
|
+
value = TypedField(str)
|
|
33
|
+
|
|
34
|
+
field = TemporaryTable.__dict__["value"]
|
|
35
|
+
db_ref = weakref.ref(db)
|
|
36
|
+
|
|
37
|
+
db.close()
|
|
38
|
+
|
|
39
|
+
assert TemporaryTable._db is None
|
|
40
|
+
assert TemporaryTable._table is None
|
|
41
|
+
assert field._table is None
|
|
42
|
+
assert field._field is None
|
|
43
|
+
|
|
44
|
+
del db
|
|
45
|
+
gc.collect()
|
|
46
|
+
|
|
47
|
+
assert db_ref() is None
|
|
48
|
+
|
|
49
|
+
|
|
25
50
|
def test_mixed_defines(capsys):
|
|
26
51
|
### DEFINE
|
|
27
52
|
|
|
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
|
|
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
|