TypeDAL 3.16.2__tar.gz → 3.16.4__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.16.2 → typedal-3.16.4}/CHANGELOG.md +12 -0
  2. {typedal-3.16.2 → typedal-3.16.4}/PKG-INFO +1 -1
  3. {typedal-3.16.2 → typedal-3.16.4}/src/typedal/__about__.py +1 -1
  4. {typedal-3.16.2 → typedal-3.16.4}/src/typedal/core.py +57 -32
  5. {typedal-3.16.2 → typedal-3.16.4}/tests/test_row.py +39 -5
  6. {typedal-3.16.2 → typedal-3.16.4}/.github/workflows/su6.yml +0 -0
  7. {typedal-3.16.2 → typedal-3.16.4}/.gitignore +0 -0
  8. {typedal-3.16.2 → typedal-3.16.4}/.readthedocs.yml +0 -0
  9. {typedal-3.16.2 → typedal-3.16.4}/README.md +0 -0
  10. {typedal-3.16.2 → typedal-3.16.4}/coverage.svg +0 -0
  11. {typedal-3.16.2 → typedal-3.16.4}/docs/1_getting_started.md +0 -0
  12. {typedal-3.16.2 → typedal-3.16.4}/docs/2_defining_tables.md +0 -0
  13. {typedal-3.16.2 → typedal-3.16.4}/docs/3_building_queries.md +0 -0
  14. {typedal-3.16.2 → typedal-3.16.4}/docs/4_relationships.md +0 -0
  15. {typedal-3.16.2 → typedal-3.16.4}/docs/5_py4web.md +0 -0
  16. {typedal-3.16.2 → typedal-3.16.4}/docs/6_migrations.md +0 -0
  17. {typedal-3.16.2 → typedal-3.16.4}/docs/7_mixins.md +0 -0
  18. {typedal-3.16.2 → typedal-3.16.4}/docs/css/code_blocks.css +0 -0
  19. {typedal-3.16.2 → typedal-3.16.4}/docs/index.md +0 -0
  20. {typedal-3.16.2 → typedal-3.16.4}/docs/requirements.txt +0 -0
  21. {typedal-3.16.2 → typedal-3.16.4}/example_new.py +0 -0
  22. {typedal-3.16.2 → typedal-3.16.4}/example_old.py +0 -0
  23. {typedal-3.16.2 → typedal-3.16.4}/mkdocs.yml +0 -0
  24. {typedal-3.16.2 → typedal-3.16.4}/pyproject.toml +0 -0
  25. {typedal-3.16.2 → typedal-3.16.4}/src/typedal/__init__.py +0 -0
  26. {typedal-3.16.2 → typedal-3.16.4}/src/typedal/caching.py +0 -0
  27. {typedal-3.16.2 → typedal-3.16.4}/src/typedal/cli.py +0 -0
  28. {typedal-3.16.2 → typedal-3.16.4}/src/typedal/config.py +0 -0
  29. {typedal-3.16.2 → typedal-3.16.4}/src/typedal/fields.py +0 -0
  30. {typedal-3.16.2 → typedal-3.16.4}/src/typedal/for_py4web.py +0 -0
  31. {typedal-3.16.2 → typedal-3.16.4}/src/typedal/for_web2py.py +0 -0
  32. {typedal-3.16.2 → typedal-3.16.4}/src/typedal/helpers.py +0 -0
  33. {typedal-3.16.2 → typedal-3.16.4}/src/typedal/mixins.py +0 -0
  34. {typedal-3.16.2 → typedal-3.16.4}/src/typedal/py.typed +0 -0
  35. {typedal-3.16.2 → typedal-3.16.4}/src/typedal/serializers/as_json.py +0 -0
  36. {typedal-3.16.2 → typedal-3.16.4}/src/typedal/types.py +0 -0
  37. {typedal-3.16.2 → typedal-3.16.4}/src/typedal/web2py_py4web_shared.py +0 -0
  38. {typedal-3.16.2 → typedal-3.16.4}/tests/__init__.py +0 -0
  39. {typedal-3.16.2 → typedal-3.16.4}/tests/configs/simple.toml +0 -0
  40. {typedal-3.16.2 → typedal-3.16.4}/tests/configs/valid.env +0 -0
  41. {typedal-3.16.2 → typedal-3.16.4}/tests/configs/valid.toml +0 -0
  42. {typedal-3.16.2 → typedal-3.16.4}/tests/test_cli.py +0 -0
  43. {typedal-3.16.2 → typedal-3.16.4}/tests/test_config.py +0 -0
  44. {typedal-3.16.2 → typedal-3.16.4}/tests/test_docs_examples.py +0 -0
  45. {typedal-3.16.2 → typedal-3.16.4}/tests/test_helpers.py +0 -0
  46. {typedal-3.16.2 → typedal-3.16.4}/tests/test_json.py +0 -0
  47. {typedal-3.16.2 → typedal-3.16.4}/tests/test_main.py +0 -0
  48. {typedal-3.16.2 → typedal-3.16.4}/tests/test_mixins.py +0 -0
  49. {typedal-3.16.2 → typedal-3.16.4}/tests/test_mypy.py +0 -0
  50. {typedal-3.16.2 → typedal-3.16.4}/tests/test_orm.py +0 -0
  51. {typedal-3.16.2 → typedal-3.16.4}/tests/test_py4web.py +0 -0
  52. {typedal-3.16.2 → typedal-3.16.4}/tests/test_query_builder.py +0 -0
  53. {typedal-3.16.2 → typedal-3.16.4}/tests/test_relationships.py +0 -0
  54. {typedal-3.16.2 → typedal-3.16.4}/tests/test_stats.py +0 -0
  55. {typedal-3.16.2 → typedal-3.16.4}/tests/test_table.py +0 -0
  56. {typedal-3.16.2 → typedal-3.16.4}/tests/test_web2py.py +0 -0
  57. {typedal-3.16.2 → typedal-3.16.4}/tests/test_xx_others.py +0 -0
  58. {typedal-3.16.2 → typedal-3.16.4}/tests/timings.py +0 -0
@@ -2,6 +2,18 @@
2
2
 
3
3
  <!--next-version-placeholder-->
4
4
 
5
+ ## v3.16.4 (2025-09-08)
6
+
7
+ ### Fix
8
+
9
+ * Support `.render()` with list:str relationships ([`e7d6d82`](https://github.com/trialandsuccess/TypeDAL/commit/e7d6d82de82034eee882ab4bc4e1ebf8178f8639))
10
+
11
+ ## v3.16.3 (2025-09-08)
12
+
13
+ ### Fix
14
+
15
+ * Support `.render()` on individual row ([`200a64c`](https://github.com/trialandsuccess/TypeDAL/commit/200a64c0e0c2647c5036dee0476d9ad8ebb416e4))
16
+
5
17
  ## v3.16.2 (2025-09-08)
6
18
 
7
19
  ### Fix
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: TypeDAL
3
- Version: 3.16.2
3
+ Version: 3.16.4
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.16.2"
8
+ __version__ = "3.16.4"
@@ -2037,6 +2037,61 @@ class TypedTable(_TypedTable, metaclass=TableMeta):
2037
2037
 
2038
2038
  return pydal2sql.generate_sql(cls)
2039
2039
 
2040
+ def render(self, fields=None, compact=False) -> Self:
2041
+ row = copy.deepcopy(self)
2042
+ keys = list(row)
2043
+ if not fields:
2044
+ fields = [self._table[f] for f in self._table._fields]
2045
+ fields = [f for f in fields if isinstance(f, Field) and f.represent]
2046
+
2047
+ for field in fields:
2048
+ if field._table == self._table:
2049
+ row[field.name] = self._db.represent(
2050
+ "rows_render",
2051
+ field,
2052
+ row[field.name],
2053
+ row,
2054
+ )
2055
+ # else: relationship, different logic:
2056
+
2057
+ for relation_name in getattr(row, "_with", []):
2058
+ if relation := self._relationships.get(relation_name):
2059
+ relation_table = relation.table
2060
+
2061
+ relation_row = row[relation_name]
2062
+
2063
+ if isinstance(relation_row, list):
2064
+ # list of rows
2065
+ combined = []
2066
+
2067
+ for related_og in relation_row:
2068
+ related = copy.deepcopy(related_og)
2069
+ for fieldname in related:
2070
+ field = relation_table[fieldname]
2071
+ related[field.name] = self._db.represent(
2072
+ "rows_render",
2073
+ field,
2074
+ related[field.name],
2075
+ related,
2076
+ )
2077
+ combined.append(related)
2078
+
2079
+ row[relation_name] = combined
2080
+ else:
2081
+ # 1 row
2082
+ for fieldname in relation_row:
2083
+ field = relation_table[fieldname]
2084
+ row[relation_name][fieldname] = self._db.represent(
2085
+ "rows_render",
2086
+ field,
2087
+ relation_row[field.name],
2088
+ relation_row,
2089
+ )
2090
+
2091
+ if compact and len(keys) == 1 and keys[0] != "_extra": # pragma: no cover
2092
+ return row[keys[0]]
2093
+ return row
2094
+
2040
2095
 
2041
2096
  # backwards compat:
2042
2097
  TypedRow = TypedTable
@@ -2431,38 +2486,8 @@ class TypedRows(typing.Collection[T_MetaInstance], Rows):
2431
2486
  "Rows.render() needs a `rows_render` representer in DAL instance",
2432
2487
  )
2433
2488
 
2434
- row = copy.deepcopy(self.records[i])
2435
- keys = list(row)
2436
- if not fields:
2437
- fields = [f for f in self.fields if isinstance(f, Field) and f.represent]
2438
-
2439
- for field in fields:
2440
- if field._table == self.model._table:
2441
- row[field.name] = self.db.represent(
2442
- "rows_render",
2443
- field,
2444
- row[field.name],
2445
- row,
2446
- )
2447
- # else: relationship, different logic:
2448
-
2449
- for relation_name in row._with:
2450
- if relation := self.model._relationships.get(relation_name):
2451
- relation_table = relation.table
2452
-
2453
- relation_row = row[relation_name]
2454
- for fieldname in relation_row:
2455
- field = relation_table[fieldname]
2456
- row[relation_name][fieldname] = self.db.represent(
2457
- "rows_render",
2458
- field,
2459
- relation_row[field.name],
2460
- relation_row,
2461
- )
2462
-
2463
- if self.compact and len(keys) == 1 and keys[0] != "_extra": # pragma: no cover
2464
- return row[keys[0]]
2465
- return row
2489
+ row = self.records[i]
2490
+ return row.render(fields, compact=self.compact)
2466
2491
 
2467
2492
 
2468
2493
  from .caching import ( # noqa: E402
@@ -240,16 +240,50 @@ def test_render():
240
240
  condition=lambda this, that: this.normal == that.also_normal,
241
241
  )
242
242
 
243
+ related_list = relationship(
244
+ list[RelatedTable],
245
+ condition=lambda this, that: this.normal == that.also_normal,
246
+ )
247
+
243
248
  RelatedTable.insert(also_normal="123")
244
249
  RenderTable.insert(normal="123", list_field=["abc", "def"])
245
250
 
246
251
  rows = RenderTable.select().join("related").collect()
247
252
 
248
- assert rows.first().related
253
+ first = rows.first()
254
+
255
+ assert first.related
256
+
257
+ iterator = rows.render()
258
+ rendered_one = next(iterator)
259
+
260
+ assert rendered_one.normal == "123"
261
+ assert rendered_one.list_field == "abc, def"
262
+ assert rendered_one.related.also_normal == "321"
263
+
264
+ # .render() on one row:
265
+ rendered_two = first.render()
266
+ assert rendered_two.normal == "123"
267
+ assert rendered_two.list_field == "abc, def"
268
+ assert rendered_two.related.also_normal == "321"
269
+
270
+ # test list:
271
+
272
+ rows = RenderTable.select().join("related_list").collect()
273
+
274
+ second = rows.first()
275
+
276
+ assert second.related_list
249
277
 
250
278
  iterator = rows.render()
251
- first = next(iterator)
279
+ rendered_three = next(iterator)
280
+
281
+ assert rendered_three.normal == "123"
282
+ assert rendered_three.list_field == "abc, def"
283
+ assert rendered_three.related_list[0].also_normal == "321"
284
+
285
+ rendered_four = second.render()
252
286
 
253
- assert first.normal == "123"
254
- assert first.list_field == "abc, def"
255
- assert first.related.also_normal == "321"
287
+ assert rendered_four.normal == "123"
288
+ assert rendered_four.list_field == "abc, def"
289
+ assert rendered_four.related_list[0].also_normal == "321"
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