TypeDAL 3.14.1__tar.gz → 3.14.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.

Potentially problematic release.


This version of TypeDAL might be problematic. Click here for more details.

Files changed (58) hide show
  1. {typedal-3.14.1 → typedal-3.14.2}/CHANGELOG.md +6 -0
  2. {typedal-3.14.1 → typedal-3.14.2}/PKG-INFO +1 -1
  3. {typedal-3.14.1 → typedal-3.14.2}/src/typedal/__about__.py +1 -1
  4. {typedal-3.14.1 → typedal-3.14.2}/src/typedal/cli.py +1 -2
  5. {typedal-3.14.1 → typedal-3.14.2}/src/typedal/fields.py +25 -2
  6. {typedal-3.14.1 → typedal-3.14.2}/tests/test_config.py +21 -4
  7. {typedal-3.14.1 → typedal-3.14.2}/.github/workflows/su6.yml +0 -0
  8. {typedal-3.14.1 → typedal-3.14.2}/.gitignore +0 -0
  9. {typedal-3.14.1 → typedal-3.14.2}/.readthedocs.yml +0 -0
  10. {typedal-3.14.1 → typedal-3.14.2}/README.md +0 -0
  11. {typedal-3.14.1 → typedal-3.14.2}/coverage.svg +0 -0
  12. {typedal-3.14.1 → typedal-3.14.2}/docs/1_getting_started.md +0 -0
  13. {typedal-3.14.1 → typedal-3.14.2}/docs/2_defining_tables.md +0 -0
  14. {typedal-3.14.1 → typedal-3.14.2}/docs/3_building_queries.md +0 -0
  15. {typedal-3.14.1 → typedal-3.14.2}/docs/4_relationships.md +0 -0
  16. {typedal-3.14.1 → typedal-3.14.2}/docs/5_py4web.md +0 -0
  17. {typedal-3.14.1 → typedal-3.14.2}/docs/6_migrations.md +0 -0
  18. {typedal-3.14.1 → typedal-3.14.2}/docs/7_mixins.md +0 -0
  19. {typedal-3.14.1 → typedal-3.14.2}/docs/css/code_blocks.css +0 -0
  20. {typedal-3.14.1 → typedal-3.14.2}/docs/index.md +0 -0
  21. {typedal-3.14.1 → typedal-3.14.2}/docs/requirements.txt +0 -0
  22. {typedal-3.14.1 → typedal-3.14.2}/example_new.py +0 -0
  23. {typedal-3.14.1 → typedal-3.14.2}/example_old.py +0 -0
  24. {typedal-3.14.1 → typedal-3.14.2}/mkdocs.yml +0 -0
  25. {typedal-3.14.1 → typedal-3.14.2}/pyproject.toml +0 -0
  26. {typedal-3.14.1 → typedal-3.14.2}/src/typedal/__init__.py +0 -0
  27. {typedal-3.14.1 → typedal-3.14.2}/src/typedal/caching.py +0 -0
  28. {typedal-3.14.1 → typedal-3.14.2}/src/typedal/config.py +0 -0
  29. {typedal-3.14.1 → typedal-3.14.2}/src/typedal/core.py +0 -0
  30. {typedal-3.14.1 → typedal-3.14.2}/src/typedal/for_py4web.py +0 -0
  31. {typedal-3.14.1 → typedal-3.14.2}/src/typedal/for_web2py.py +0 -0
  32. {typedal-3.14.1 → typedal-3.14.2}/src/typedal/helpers.py +0 -0
  33. {typedal-3.14.1 → typedal-3.14.2}/src/typedal/mixins.py +0 -0
  34. {typedal-3.14.1 → typedal-3.14.2}/src/typedal/py.typed +0 -0
  35. {typedal-3.14.1 → typedal-3.14.2}/src/typedal/serializers/as_json.py +0 -0
  36. {typedal-3.14.1 → typedal-3.14.2}/src/typedal/types.py +0 -0
  37. {typedal-3.14.1 → typedal-3.14.2}/src/typedal/web2py_py4web_shared.py +0 -0
  38. {typedal-3.14.1 → typedal-3.14.2}/tests/__init__.py +0 -0
  39. {typedal-3.14.1 → typedal-3.14.2}/tests/configs/simple.toml +0 -0
  40. {typedal-3.14.1 → typedal-3.14.2}/tests/configs/valid.env +0 -0
  41. {typedal-3.14.1 → typedal-3.14.2}/tests/configs/valid.toml +0 -0
  42. {typedal-3.14.1 → typedal-3.14.2}/tests/test_cli.py +0 -0
  43. {typedal-3.14.1 → typedal-3.14.2}/tests/test_docs_examples.py +0 -0
  44. {typedal-3.14.1 → typedal-3.14.2}/tests/test_helpers.py +0 -0
  45. {typedal-3.14.1 → typedal-3.14.2}/tests/test_json.py +0 -0
  46. {typedal-3.14.1 → typedal-3.14.2}/tests/test_main.py +0 -0
  47. {typedal-3.14.1 → typedal-3.14.2}/tests/test_mixins.py +0 -0
  48. {typedal-3.14.1 → typedal-3.14.2}/tests/test_mypy.py +0 -0
  49. {typedal-3.14.1 → typedal-3.14.2}/tests/test_orm.py +0 -0
  50. {typedal-3.14.1 → typedal-3.14.2}/tests/test_py4web.py +0 -0
  51. {typedal-3.14.1 → typedal-3.14.2}/tests/test_query_builder.py +0 -0
  52. {typedal-3.14.1 → typedal-3.14.2}/tests/test_relationships.py +0 -0
  53. {typedal-3.14.1 → typedal-3.14.2}/tests/test_row.py +0 -0
  54. {typedal-3.14.1 → typedal-3.14.2}/tests/test_stats.py +0 -0
  55. {typedal-3.14.1 → typedal-3.14.2}/tests/test_table.py +0 -0
  56. {typedal-3.14.1 → typedal-3.14.2}/tests/test_web2py.py +0 -0
  57. {typedal-3.14.1 → typedal-3.14.2}/tests/test_xx_others.py +0 -0
  58. {typedal-3.14.1 → typedal-3.14.2}/tests/timings.py +0 -0
@@ -2,6 +2,12 @@
2
2
 
3
3
  <!--next-version-placeholder-->
4
4
 
5
+ ## v3.14.2 (2025-06-05)
6
+
7
+ ### Fix
8
+
9
+ * **PointField:** Don't crash if invalid point is parsed ([`e14b4a3`](https://github.com/trialandsuccess/TypeDAL/commit/e14b4a349799799cc94e8fb62d9da9a0fafdcd36))
10
+
5
11
  ## v3.14.1 (2025-05-27)
6
12
 
7
13
  ### Fix
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: TypeDAL
3
- Version: 3.14.1
3
+ Version: 3.14.2
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
@@ -5,4 +5,4 @@ This file contains the Version info for this package.
5
5
  # SPDX-FileCopyrightText: 2023-present Robin van der Noord <robinvandernoord@gmail.com>
6
6
  #
7
7
  # SPDX-License-Identifier: MIT
8
- __version__ = "3.14.1"
8
+ __version__ = "3.14.2"
@@ -392,8 +392,7 @@ def fake_migrations(
392
392
 
393
393
  previously_migrated = (
394
394
  db(
395
- db.ewh_implemented_features.name.belongs(to_fake)
396
- & (db.ewh_implemented_features.installed == True) # noqa E712
395
+ db.ewh_implemented_features.name.belongs(to_fake) & (db.ewh_implemented_features.installed == True) # noqa E712
397
396
  )
398
397
  .select(db.ewh_implemented_features.name)
399
398
  .column("name")
@@ -256,11 +256,34 @@ def TimestampField(**kw: Unpack[FieldSettings]) -> TypedField[dt.datetime]:
256
256
  )
257
257
 
258
258
 
259
+ def safe_decode_native_point(value: str | None):
260
+ if not value:
261
+ return ()
262
+
263
+ try:
264
+ return ast.literal_eval(value)
265
+ except ValueError: # pragma: no cover
266
+ # should not happen when inserted with `safe_encode_native_point` but you never know
267
+ return ()
268
+
269
+
270
+ def safe_encode_native_point(value):
271
+ if not value:
272
+ return ""
273
+
274
+ if isinstance(value, str):
275
+ value = tuple(float(_) for _ in value.strip("(").strip(")").split(","))
276
+ if not (isinstance(value, tuple) and len(value) == 2):
277
+ raise ValueError("Invalid point tuple")
278
+
279
+ return str(value)
280
+
281
+
259
282
  NativePointField = SQLCustomType(
260
283
  type="string",
261
284
  native="point",
262
- encoder=str,
263
- decoder=ast.literal_eval,
285
+ encoder=safe_encode_native_point,
286
+ decoder=safe_decode_native_point,
264
287
  )
265
288
 
266
289
 
@@ -219,7 +219,11 @@ def test_point_fields_sqlite(at_temp_dir):
219
219
  class Point(TypedTable):
220
220
  pt = PointField()
221
221
 
222
+ class OptionalPoint(TypedTable):
223
+ maybe_pt = PointField(notnull=False)
224
+
222
225
  db.define(Point)
226
+ db.define(OptionalPoint)
223
227
 
224
228
  row1 = Point.insert(pt=(1, 0))
225
229
  row2 = Point.insert(pt="(1, 0)")
@@ -236,8 +240,13 @@ def test_point_fields_sqlite(at_temp_dir):
236
240
  with pytest.raises(Exception):
237
241
  Point.insert(pt="123")
238
242
 
239
- # note: psql will check this whereas sqlite won't:
240
- Point.insert(pt=())
243
+ with pytest.raises(Exception):
244
+ Point.insert(pt=())
245
+
246
+ db.rollback()
247
+
248
+ row3 = OptionalPoint.insert(maybe_pt=())
249
+ assert row3.maybe_pt == ()
241
250
 
242
251
  assert '"pt" point NOT NULL' in Point._sql()
243
252
 
@@ -253,7 +262,11 @@ def test_point_fields_psql(at_temp_dir):
253
262
  class Point(TypedTable):
254
263
  pt = PointField()
255
264
 
265
+ class OptionalPoint(TypedTable):
266
+ maybe_pt = PointField(notnull=False)
267
+
256
268
  db.define(Point)
269
+ db.define(OptionalPoint)
257
270
 
258
271
  row1 = Point.insert(pt=(1, 0))
259
272
  row2 = Point.insert(pt="(1, 0)")
@@ -270,12 +283,16 @@ def test_point_fields_psql(at_temp_dir):
270
283
  with pytest.raises(Exception):
271
284
  Point.insert(pt="123")
272
285
 
273
- # note: psql will check this whereas sqlite won't:
274
-
275
286
  with pytest.raises(Exception):
276
287
  Point.insert(pt=())
277
288
 
289
+ db.rollback()
290
+
291
+ row3 = OptionalPoint.insert(maybe_pt=())
292
+ assert row3.maybe_pt == ()
293
+
278
294
  assert '"pt" point NOT NULL' in Point._sql()
295
+ assert "NOT NULL" not in OptionalPoint._sql()
279
296
 
280
297
 
281
298
  def test_uuid_fields_psql(at_temp_dir):
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