TypeDAL 5.0.4__tar.gz → 5.0.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.
Files changed (28) hide show
  1. {typedal-5.0.4 → typedal-5.0.6}/PKG-INFO +1 -1
  2. {typedal-5.0.4 → typedal-5.0.6}/pyproject.toml +1 -1
  3. {typedal-5.0.4 → typedal-5.0.6}/pyproject.toml.orig +1 -1
  4. {typedal-5.0.4 → typedal-5.0.6}/src/typedal/caching.py +1 -2
  5. {typedal-5.0.4 → typedal-5.0.6}/src/typedal/core.py +5 -5
  6. {typedal-5.0.4 → typedal-5.0.6}/src/typedal/define.py +1 -2
  7. {typedal-5.0.4 → typedal-5.0.6}/src/typedal/fields.py +6 -5
  8. {typedal-5.0.4 → typedal-5.0.6}/src/typedal/query_builder.py +13 -12
  9. {typedal-5.0.4 → typedal-5.0.6}/src/typedal/relationships.py +3 -5
  10. {typedal-5.0.4 → typedal-5.0.6}/src/typedal/rows.py +30 -7
  11. {typedal-5.0.4 → typedal-5.0.6}/src/typedal/tables.py +20 -8
  12. {typedal-5.0.4 → typedal-5.0.6}/src/typedal/types.py +38 -54
  13. {typedal-5.0.4 → typedal-5.0.6}/README.md +0 -0
  14. {typedal-5.0.4 → typedal-5.0.6}/src/typedal/__about__.py +0 -0
  15. {typedal-5.0.4 → typedal-5.0.6}/src/typedal/__init__.py +0 -0
  16. {typedal-5.0.4 → typedal-5.0.6}/src/typedal/asynchronous.py +0 -0
  17. {typedal-5.0.4 → typedal-5.0.6}/src/typedal/cli.py +0 -0
  18. {typedal-5.0.4 → typedal-5.0.6}/src/typedal/config.py +0 -0
  19. {typedal-5.0.4 → typedal-5.0.6}/src/typedal/constants.py +0 -0
  20. {typedal-5.0.4 → typedal-5.0.6}/src/typedal/enum_helpers.py +0 -0
  21. {typedal-5.0.4 → typedal-5.0.6}/src/typedal/for_py4web.py +0 -0
  22. {typedal-5.0.4 → typedal-5.0.6}/src/typedal/for_web2py.py +0 -0
  23. {typedal-5.0.4 → typedal-5.0.6}/src/typedal/helpers.py +0 -0
  24. {typedal-5.0.4 → typedal-5.0.6}/src/typedal/mixins.py +0 -0
  25. {typedal-5.0.4 → typedal-5.0.6}/src/typedal/py.typed +0 -0
  26. {typedal-5.0.4 → typedal-5.0.6}/src/typedal/serializers/as_json.py +0 -0
  27. {typedal-5.0.4 → typedal-5.0.6}/src/typedal/serializers/typescript.py +0 -0
  28. {typedal-5.0.4 → typedal-5.0.6}/src/typedal/web2py_py4web_shared.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: TypeDAL
3
- Version: 5.0.4
3
+ Version: 5.0.6
4
4
  Summary: Typing support for PyDAL
5
5
  Keywords:
6
6
  Author: Robin van der Noord
@@ -6,7 +6,7 @@ build-backend = "uv_build"
6
6
  name = "TypeDAL"
7
7
  description = "Typing support for PyDAL"
8
8
  readme = "README.md"
9
- version = "5.0.4"
9
+ version = "5.0.6"
10
10
  requires-python = ">=3.12"
11
11
  license-expression = "MIT"
12
12
  keywords = []
@@ -6,7 +6,7 @@ build-backend = "uv_build"
6
6
  name = "TypeDAL"
7
7
  description = 'Typing support for PyDAL'
8
8
  readme = "README.md"
9
- version = "5.0.4"
9
+ version = "5.0.6"
10
10
  requires-python = ">=3.12"
11
11
  license-expression = "MIT"
12
12
  keywords = []
@@ -9,13 +9,12 @@ import json
9
9
  import typing as t
10
10
 
11
11
  import dill # nosec
12
- from pydal.objects import Field, Rows, Set
13
12
 
14
13
  from .fields import TypedField
15
14
  from .helpers import throw
16
15
  from .rows import TypedRows
17
16
  from .tables import TypedTable
18
- from .types import CacheStatus, Query
17
+ from .types import CacheStatus, Field, Query, Rows, Set
19
18
 
20
19
  if t.TYPE_CHECKING:
21
20
  from .core import TypeDAL
@@ -51,10 +51,10 @@ if t.TYPE_CHECKING:
51
51
 
52
52
  def _expression_subclasses() -> t.Iterator[type]:
53
53
  """
54
- Yield pydal.objects.Expression and every (nested) subclass currently loaded, e.g. Field and TypedField.
54
+ Yield Expression and every (nested) subclass currently loaded, e.g. Field and TypedField.
55
55
  """
56
- seen = {pydal.objects.Expression}
57
- stack = [pydal.objects.Expression]
56
+ seen = {Expression}
57
+ stack = [Expression]
58
58
  while stack:
59
59
  for subclass in stack.pop().__subclasses__():
60
60
  if subclass not in seen:
@@ -77,7 +77,7 @@ def _purge_dialect_expressions(adapter: t.Any) -> None:
77
77
  `gc.collect()` will not free it, and with it the entire db (tables, fields, models)
78
78
  it belongs to, for the lifetime of the process, unless explicitly undone here.
79
79
  """
80
- expressions = pydal.objects.Expression._dialect_expressions_
80
+ expressions = Expression._dialect_expressions_
81
81
  stale = [
82
82
  name
83
83
  for name, wrapper in expressions.items()
@@ -544,7 +544,7 @@ class TypeDAL(_TypeDALBase):
544
544
 
545
545
  return wrapper
546
546
 
547
- def __call__(self, *_args: T_Query, **kwargs: t.Any) -> "TypedSet": # ty: ignore[invalid-method-override]
547
+ def __call__(self, *_args: T_Query, **kwargs: t.Any) -> "TypedSet":
548
548
  """
549
549
  A db instance can be called directly to perform a query.
550
550
 
@@ -12,7 +12,6 @@ import types
12
12
  import typing as t
13
13
  import warnings
14
14
 
15
- import pydal
16
15
  from pydal.validators import IS_IN_SET, ValidationError, Validator
17
16
 
18
17
  from .constants import BASIC_MAPPINGS
@@ -163,7 +162,7 @@ class TableDefinitionBuilder:
163
162
  if mapping := BASIC_MAPPINGS.get(ftype):
164
163
  # basi types
165
164
  return mapping
166
- elif isinstance(ftype, pydal.objects.Table):
165
+ elif isinstance(ftype, Table):
167
166
  # db.table
168
167
  return f"reference {ftype._tablename}"
169
168
  elif issubclass(type(ftype), type) and issubclass(ftype, TypedTable):
@@ -14,7 +14,6 @@ import uuid
14
14
 
15
15
  import pydal
16
16
  from pydal.helpers.classes import SQLCustomType
17
- from pydal.objects import Table
18
17
 
19
18
  from .core import TypeDAL
20
19
  from .types import (
@@ -26,6 +25,7 @@ from .types import (
26
25
  Query,
27
26
  T_annotation,
28
27
  T_MetaInstance,
28
+ Table,
29
29
  Validator,
30
30
  )
31
31
 
@@ -79,7 +79,7 @@ class TypedField[T_Value](Expression): # pragma: no cover
79
79
  authorize: AnyCallable | None
80
80
  autodelete: bool
81
81
  requires: Validator | t.Iterable[Validator]
82
- represent: t.Callable[[T_Value, TypedTable | None], t.Any]
82
+ represent: t.Callable[[T_Value, t.Any], t.Any] # second argument is the model class but we can't type that
83
83
  compute: AnyCallable | None
84
84
  custom_store: AnyCallable | None
85
85
  custom_retrieve: AnyCallable | None
@@ -190,12 +190,12 @@ class TypedField[T_Value](Expression): # pragma: no cover
190
190
  extra_kwargs,
191
191
  )
192
192
 
193
- def bind(self, field: pydal.objects.Field, table: pydal.objects.Table) -> None:
193
+ def bind(self, field: Field, table: Table) -> None:
194
194
  """
195
195
  Bind the right db/table/field info to this class, so queries can be made using `Class.field == ...`.
196
196
  """
197
197
  self._table = table
198
- self._field = t.cast(Field, field)
198
+ self._field = field
199
199
 
200
200
  def unbind(self) -> None:
201
201
  """Remove references to the pydal objects created during `bind`."""
@@ -280,7 +280,7 @@ class TypedField[T_Value](Expression): # pragma: no cover
280
280
  return t.cast(Expression, self._field.lower())
281
281
 
282
282
 
283
- def rname(field: TypedField[t.Any] | Field | pydal.objects.Field) -> str:
283
+ def rname(field: TypedField[t.Any] | Field) -> str:
284
284
  """
285
285
  Return the full rname (table and field).
286
286
  """
@@ -514,6 +514,7 @@ def BigintField(**kw: t.Unpack[FieldSettings]) -> TypedField[int]:
514
514
 
515
515
  Bigint = BigintField
516
516
 
517
+
517
518
  ## Custom:
518
519
 
519
520
 
@@ -10,7 +10,7 @@ import time
10
10
  import typing as t
11
11
  from collections import defaultdict
12
12
 
13
- import pydal.objects
13
+ from pydal.helpers.classes import SQLALL
14
14
 
15
15
  from .asynchronous import run_async
16
16
  from .constants import DEFAULT_JOIN_OPTION, JOIN_OPTIONS
@@ -38,6 +38,7 @@ from .types import (
38
38
  Query,
39
39
  Row,
40
40
  Rows,
41
+ Select,
41
42
  SelectKwargs,
42
43
  T_MetaInstance,
43
44
  Table,
@@ -46,7 +47,7 @@ from .types import (
46
47
  )
47
48
 
48
49
 
49
- class QueryBuilder[T_MetaInstance: _TypedTable](pydal.objects.Select):
50
+ class QueryBuilder[T_MetaInstance: _TypedTable](Select):
50
51
  """
51
52
  Abstration on top of pydal's query system.
52
53
  """
@@ -290,9 +291,9 @@ class QueryBuilder[T_MetaInstance: _TypedTable](pydal.objects.Select):
290
291
 
291
292
  subquery = t.cast(Query, DummyQuery())
292
293
  for query_part in queries_or_lambdas:
293
- if isinstance(query_part, (Field, pydal.objects.Field)) or is_typed_field(query_part):
294
- subquery |= t.cast(Query, query_part != None)
295
- elif isinstance(query_part, (pydal.objects.Query, Expression, pydal.objects.Expression)):
294
+ if isinstance(query_part, Field) or is_typed_field(query_part):
295
+ subquery |= query_part != None
296
+ elif isinstance(query_part, (Query, Expression)):
296
297
  subquery |= t.cast(Query, query_part)
297
298
  elif callable(query_part):
298
299
  if result := query_part(self.model): # ty: ignore[call-top-callable]
@@ -401,7 +402,7 @@ class QueryBuilder[T_MetaInstance: _TypedTable](pydal.objects.Select):
401
402
  if len(fields) != 1:
402
403
  raise ValueError("join(field, condition=...) can only be used with exactly one field!")
403
404
 
404
- if isinstance(condition, pydal.objects.Query):
405
+ if isinstance(condition, Query):
405
406
  condition = as_lambda(condition)
406
407
 
407
408
  field = fields[0]
@@ -418,8 +419,8 @@ class QueryBuilder[T_MetaInstance: _TypedTable](pydal.objects.Select):
418
419
  if len(fields) != 1:
419
420
  raise ValueError("join(field, on=...) can only be used with exactly one field!")
420
421
 
421
- if isinstance(on, pydal.objects.Expression):
422
- on = t.cast(list[Expression], [on])
422
+ if isinstance(on, Expression):
423
+ on = [on]
423
424
 
424
425
  if isinstance(on, list):
425
426
  on = t.cast(OnQuery, as_lambda(on))
@@ -856,7 +857,7 @@ class QueryBuilder[T_MetaInstance: _TypedTable](pydal.objects.Select):
856
857
  expression_without_direction, _, direction = expression.rpartition(" ")
857
858
  return [expression_without_direction if direction.upper() in {"ASC", "DESC"} else orderby]
858
859
 
859
- if isinstance(orderby, pydal.objects.Field):
860
+ if isinstance(orderby, Field):
860
861
  return t.cast(list[OrderBy], [orderby])
861
862
 
862
863
  fields = []
@@ -968,8 +969,8 @@ class QueryBuilder[T_MetaInstance: _TypedTable](pydal.objects.Select):
968
969
  if not isinstance(on, list):
969
970
  on = [on]
970
971
 
971
- on = [_ for _ in on if isinstance(_, pydal.objects.Expression)]
972
- left_joins.extend(on) # ty: ignore[invalid-argument-type]
972
+ on = [_ for _ in on if isinstance(_, Expression)]
973
+ left_joins.extend(on)
973
974
  elif method == "left":
974
975
  # Generate left join condition
975
976
  if not is_self_reference:
@@ -1032,7 +1033,7 @@ class QueryBuilder[T_MetaInstance: _TypedTable](pydal.objects.Select):
1032
1033
  if pre_alias != post_alias:
1033
1034
  updated_args = []
1034
1035
  for arg in select_args:
1035
- if isinstance(arg, pydal.objects.SQLALL):
1036
+ if isinstance(arg, SQLALL):
1036
1037
  updated_args.extend(str(field).replace(f"{pre_alias}.", f"{post_alias}.") for field in arg._table)
1037
1038
  else:
1038
1039
  updated_args.append(str(arg).replace(f"{pre_alias}.", f"{post_alias}."))
@@ -6,14 +6,12 @@ import inspect
6
6
  import typing as t
7
7
  import warnings
8
8
 
9
- import pydal.objects
10
-
11
9
  from .config import LazyPolicy
12
10
  from .constants import JOIN_OPTIONS
13
11
  from .core import ForwardRef, TypeDAL, evaluate_forward_reference
14
12
  from .fields import TypedField
15
13
  from .helpers import extract_type_optional, looks_like, unwrap_type
16
- from .types import Condition, OnQuery, T_Field
14
+ from .types import Condition, OnQuery, T_Field, Table
17
15
 
18
16
  # default lazy policy is defined at the TypeDAL() instance settings level
19
17
 
@@ -199,7 +197,7 @@ class Relationship[To_Type]:
199
197
  if isinstance(self.table, str):
200
198
  return self.table
201
199
 
202
- if isinstance(self.table, pydal.objects.Table):
200
+ if isinstance(self.table, Table):
203
201
  return str(self.table)
204
202
 
205
203
  # else: typed table
@@ -288,7 +286,7 @@ class Relationship[To_Type]:
288
286
  resolved_table = self.get_table(instance._db)
289
287
 
290
288
  builder = owner.where(id=instance.id).join(self.name)
291
- if issubclass(resolved_table, TypedTable) or isinstance(resolved_table, pydal.objects.Table):
289
+ if issubclass(resolved_table, TypedTable) or isinstance(resolved_table, Table):
292
290
  # is a table so we can select ALL and ignore non-required fields of parent row:
293
291
  builder = builder.select(owner.id, resolved_table.ALL)
294
292
 
@@ -8,8 +8,6 @@ import csv
8
8
  import json
9
9
  import typing as t
10
10
 
11
- import pydal.objects
12
-
13
11
  from .asynchronous import run_async
14
12
  from .core import TypeDAL
15
13
  from .helpers import mktable
@@ -25,6 +23,7 @@ from .types import (
25
23
  Query,
26
24
  Row,
27
25
  Rows,
26
+ Set,
28
27
  T_MetaInstance,
29
28
  )
30
29
 
@@ -199,18 +198,42 @@ class TypedRows(t.Collection[T_MetaInstance], Rows):
199
198
 
200
199
  return mktable(data, headers)
201
200
 
202
- def group_by_value[T: t.Any, T_MetaInstance: _TypedTable]( # ty: ignore[shadowed-type-variable]
201
+ @t.overload
202
+ def group_by_value[T: t.Any](
203
+ self,
204
+ *fields: "TypedField[T] | str | Field",
205
+ one_result: t.Literal[True],
206
+ **kwargs: t.Any,
207
+ ) -> dict[T, T_MetaInstance]: ...
208
+
209
+ @t.overload
210
+ def group_by_value[T: t.Any](
211
+ self,
212
+ *fields: "TypedField[T] | str | Field",
213
+ one_result: t.Literal[False] = False,
214
+ **kwargs: t.Any,
215
+ ) -> dict[T, list[T_MetaInstance]]: ...
216
+
217
+ @t.overload
218
+ def group_by_value[T: t.Any](
219
+ self,
220
+ *fields: "TypedField[T] | str | Field",
221
+ one_result: bool,
222
+ **kwargs: t.Any,
223
+ ) -> dict[T, T_MetaInstance] | dict[T, list[T_MetaInstance]]: ...
224
+
225
+ def group_by_value[T: t.Any](
203
226
  self,
204
- *fields: "str | Field | TypedField[T]",
227
+ *fields: "TypedField[T] | str | Field",
205
228
  one_result: bool = False,
206
229
  **kwargs: t.Any,
207
- ) -> dict[T, list[T_MetaInstance]]:
230
+ ) -> dict[T, T_MetaInstance] | dict[T, list[T_MetaInstance]]:
208
231
  """
209
232
  Group the rows by a specific field (which will be the dict key).
210
233
  """
211
234
  kwargs["one_result"] = one_result
212
235
  result = super().group_by_value(*fields, **kwargs)
213
- return t.cast(dict[T, list[T_MetaInstance]], result)
236
+ return t.cast(dict[T, T_MetaInstance] | dict[T, list[T_MetaInstance]], result)
214
237
 
215
238
  def as_csv(self) -> str:
216
239
  """
@@ -533,7 +556,7 @@ class PaginatedRows(TypedRows[T_MetaInstance]):
533
556
  return {"data": super().as_dict(), "pagination": self.pagination}
534
557
 
535
558
 
536
- class TypedSet(pydal.objects.Set): # pragma: no cover
559
+ class TypedSet(Set): # pragma: no cover
537
560
  """
538
561
  Used to make pydal Set more typed.
539
562
 
@@ -13,9 +13,9 @@ import types
13
13
  import typing as t
14
14
  import uuid
15
15
 
16
- import pydal.objects
16
+ import pydal
17
17
  from pydal._globals import DEFAULT
18
- from pydal.helpers.classes import SQLCallableList
18
+ from pydal.helpers.classes import SQLALL, SQLCallableList
19
19
 
20
20
  from .asynchronous import run_async
21
21
  from .constants import JOIN_OPTIONS
@@ -50,7 +50,7 @@ if t.TYPE_CHECKING:
50
50
 
51
51
 
52
52
  def reorder_fields(
53
- table: pydal.objects.Table,
53
+ table: Table,
54
54
  fields: t.Iterable[str | TypedField[t.Any] | Field],
55
55
  keep_others: bool = True,
56
56
  ) -> None:
@@ -65,7 +65,7 @@ def reorder_fields(
65
65
  - False: remove other fields (only keep what's specified).
66
66
  """
67
67
  # Normalize input to field names
68
- desired = [f.name if isinstance(f, (TypedField, Field, pydal.objects.Field)) else str(f) for f in fields]
68
+ desired = [f.name if isinstance(f, (TypedField, Field)) else str(f) for f in fields]
69
69
 
70
70
  new_order = [f for f in desired if f in table._fields]
71
71
 
@@ -105,6 +105,8 @@ class TableMeta(type):
105
105
  _table: Table | None = None
106
106
  _relationships: dict[str, Relationship[t.Any]] | None = None
107
107
  _permissions: Permissions | None = None
108
+ _singular: str
109
+ _plural: str
108
110
 
109
111
  #########################
110
112
  # TypeDAL custom logic: #
@@ -149,6 +151,14 @@ class TableMeta(type):
149
151
 
150
152
  return None
151
153
 
154
+ def __setattr__(self, name: str, value: t.Any) -> None:
155
+ """Keep PyDAL's table label metadata in sync with its model class."""
156
+ if name.startswith("_") and self._table is not None:
157
+ # include base table for internal stuff such as _singular/_plural:
158
+ setattr(self._table, name, value)
159
+
160
+ super().__setattr__(name, value)
161
+
152
162
  def _ensure_table_defined(self) -> Table:
153
163
  if not self._table:
154
164
  raise EnvironmentError("@define or db.define is not called on this class yet!")
@@ -182,7 +192,7 @@ class TableMeta(type):
182
192
  else:
183
193
  return f"<unbound table {self.__name__}>"
184
194
 
185
- def from_row(self: t.Type[T_MetaInstance], row: pydal.objects.Row) -> T_MetaInstance:
195
+ def from_row(self: t.Type[T_MetaInstance], row: Row) -> T_MetaInstance:
186
196
  """
187
197
  Create a model instance from a pydal row.
188
198
  """
@@ -642,7 +652,7 @@ class TableMeta(type):
642
652
  return await QueryBuilder(self).collect_into_async(into=into, verbose=verbose, init=init)
643
653
 
644
654
  @property
645
- def ALL(cls) -> pydal.objects.SQLALL:
655
+ def ALL(cls) -> SQLALL:
646
656
  """
647
657
  Select all fields for this table.
648
658
  """
@@ -931,6 +941,8 @@ class _TypedTable(metaclass=TableMeta):
931
941
  _after_delete: list[t.Callable[[Set], t.Optional[bool]]]
932
942
  _rows: tuple[Row, ...]
933
943
  _with: list[str]
944
+ _singular: t.ClassVar[str]
945
+ _plural: t.ClassVar[str]
934
946
 
935
947
  @classmethod
936
948
  def __on_define__(cls, db: TypeDAL) -> None:
@@ -1131,7 +1143,7 @@ class TypedTable(_TypedTable, metaclass=TableMeta):
1131
1143
 
1132
1144
  def __new__(
1133
1145
  cls,
1134
- row_or_id: t.Union[Row, Query, pydal.objects.Set, int, str, "TypedTable", None] = None,
1146
+ row_or_id: t.Union[Row, Query, Set, int, str, "TypedTable", None] = None,
1135
1147
  **filters: t.Any,
1136
1148
  ) -> t.Self:
1137
1149
  """
@@ -1149,7 +1161,7 @@ class TypedTable(_TypedTable, metaclass=TableMeta):
1149
1161
  # existing typed table instance!
1150
1162
  return t.cast(t.Self, row_or_id)
1151
1163
 
1152
- elif isinstance(row_or_id, pydal.objects.Row):
1164
+ elif isinstance(row_or_id, Row):
1153
1165
  row = row_or_id
1154
1166
  elif row_or_id is not None:
1155
1167
  row = table(row_or_id, **filters)
@@ -20,6 +20,7 @@ from pydal.objects import Field as _Field
20
20
  from pydal.objects import Query as _Query
21
21
  from pydal.objects import Row as _Row
22
22
  from pydal.objects import Rows as _Rows
23
+ from pydal.objects import Select as _Select
23
24
  from pydal.objects import Set as _Set
24
25
  from pydal.objects import Table as _Table
25
26
  from pydal.validators import Validator as _Validator
@@ -147,20 +148,26 @@ class FileSystemLike(t.Protocol): # pragma: no cover
147
148
  # pydal Wrappers (to help mypy understand these classes)
148
149
  # ---------------------------------------------------------------------------
149
150
 
151
+ # same for typing and runtime:
152
+ Row: t.TypeAlias = _Row
153
+ Validator: t.TypeAlias = _Validator
154
+ Table: t.TypeAlias = _Table
155
+ Reference: t.TypeAlias = _Reference
150
156
 
151
- class Query(_Query):
152
- """Pydal Query object. Makes mypy happy."""
153
-
154
-
155
- class Expression(_Expression):
156
- """Pydal Expression object. Make mypy happy."""
157
+ # has to be (fake) subclass during type-checking:
158
+ if t.TYPE_CHECKING:
157
159
 
160
+ class Query(_Query):
161
+ """Pydal Query object. Makes mypy happy."""
158
162
 
159
- class Set(_Set):
160
- """Pydal Set object. Make mypy happy."""
163
+ class Expression(_Expression):
164
+ """Pydal Expression object. Makes mypy happy."""
161
165
 
166
+ class Set(_Set):
167
+ """Pydal Set object. Makes mypy happy."""
162
168
 
163
- if t.TYPE_CHECKING:
169
+ class Select(_Select):
170
+ """Pydal Select object. Makes mypy happy."""
164
171
 
165
172
  class OpRow:
166
173
  """
@@ -188,57 +195,34 @@ if t.TYPE_CHECKING:
188
195
  def values(self) -> t.Iterable[t.Any]:
189
196
  """Dictionary-like value iteration."""
190
197
 
191
- else:
192
-
193
- class OpRow(_OpRow):
194
- """Runtime OpRow, using pydal's version."""
195
-
196
-
197
- class Reference(_Reference):
198
- """Pydal Reference object. Make mypy happy."""
199
-
200
-
201
- class Field(_Field):
202
- """Pydal Field object. Make mypy happy."""
203
-
204
- _rname: str
198
+ class Field(_Field):
199
+ """Pydal Field object. Make mypy happy."""
205
200
 
206
- def __eq__(self, other: t.Any) -> Query: # type: ignore[override]
207
- """Comparing fields produces a PyDAL query."""
208
- return t.cast(Query, super().__eq__(other))
201
+ _rname: str
209
202
 
210
- def __ne__(self, other: t.Any) -> Query: # type: ignore[override]
211
- """Comparing fields produces a PyDAL query."""
212
- return t.cast(Query, super().__ne__(other))
203
+ def __eq__(self, other: t.Any) -> Query: # ty: ignore[invalid-method-override]
204
+ """Comparing fields produces a PyDAL query."""
205
+ return t.cast(Query, super().__eq__(other))
213
206
 
214
- def __hash__(self) -> int:
215
- """Keep fields hashable after overriding equality."""
216
- return super().__hash__()
207
+ def __ne__(self, other: t.Any) -> Query: # ty: ignore[invalid-method-override]
208
+ """Comparing fields produces a PyDAL query."""
209
+ return t.cast(Query, super().__ne__(other))
217
210
 
211
+ def __hash__(self) -> int:
212
+ """Keep fields hashable after overriding equality."""
213
+ return super().__hash__()
218
214
 
219
- class Rows(_Rows):
220
- """Pydal Rows object. Make mypy happy."""
215
+ class Rows(_Rows):
216
+ def column(self, column: t.Any = None) -> list[t.Any]: ...
221
217
 
222
- def column(self, column: t.Any = None) -> list[t.Any]:
223
- """
224
- Get a list of all values in a specific column.
225
-
226
- Example:
227
- rows.column('name') -> ['Name 1', 'Name 2', ...]
228
- """
229
- return [r[str(column) if column else self.colnames[0]] for r in self]
230
-
231
-
232
- class Row(_Row):
233
- """Pydal Row object. Make mypy happy."""
234
-
235
-
236
- class Validator(_Validator):
237
- """Pydal Validator object. Make mypy happy."""
238
-
239
-
240
- class Table(_Table):
241
- """Pydal Table object. Make mypy happy."""
218
+ else:
219
+ Query: t.TypeAlias = _Query
220
+ Expression: t.TypeAlias = _Expression
221
+ Set: t.TypeAlias = _Set
222
+ Select: t.TypeAlias = _Select
223
+ Rows: t.TypeAlias = _Rows
224
+ OpRow: t.TypeAlias = _OpRow
225
+ Field: t.TypeAlias = _Field
242
226
 
243
227
 
244
228
  # ---------------------------------------------------------------------------
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes