Coverage for src/typedal/fields.py: 100%
88 statements
« prev ^ index » next coverage.py v7.2.7, created at 2023-06-27 17:35 +0200
« prev ^ index » next coverage.py v7.2.7, created at 2023-06-27 17:35 +0200
1"""
2This file contains available Field types.
3"""
5import datetime as dt
6import decimal
7import types
8import typing
10from pydal.objects import Table
12from .core import TypeDAL, TypedFieldType, TypedTable
14T = typing.TypeVar("T", bound=typing.Any)
17## general
20def TypedField(
21 _type: typing.Type[T] | types.UnionType,
22 **kwargs: typing.Any,
23) -> T:
24 """
25 sneaky: its a function and not a class, because there's a return type.
27 and the return type (T) is the input type in _type
29 Example:
30 age: TypedField(int, default=18)
31 """
32 return typing.cast(T, TypedFieldType(_type, **kwargs))
35## specific
36def StringField(**kw: typing.Any) -> str:
37 """
38 Pydal type is string, Python type is str.
39 """
40 kw["type"] = "string"
41 return TypedField(str, **kw)
44String = StringField
47def TextField(**kw: typing.Any) -> str:
48 """
49 Pydal type is text, Python type is str.
50 """
51 kw["type"] = "text"
52 return TypedField(str, **kw)
55Text = TextField
58def BlobField(**kw: typing.Any) -> bytes:
59 """
60 Pydal type is blob, Python type is bytes.
61 """
62 kw["type"] = "blob"
63 return TypedField(bytes, **kw)
66Blob = BlobField
69def BooleanField(**kw: typing.Any) -> bool:
70 """
71 Pydal type is boolean, Python type is bool.
72 """
73 kw["type"] = "boolean"
74 return TypedField(bool, **kw)
77Boolean = BooleanField
80def IntegerField(**kw: typing.Any) -> int:
81 """
82 Pydal type is integer, Python type is int.
83 """
84 kw["type"] = "integer"
85 return TypedField(int, **kw)
88Integer = IntegerField
91def DoubleField(**kw: typing.Any) -> float:
92 """
93 Pydal type is double, Python type is float.
94 """
95 kw["type"] = "double"
96 return TypedField(float, **kw)
99Double = DoubleField
102def DecimalField(n: int, m: int, **kw: typing.Any) -> decimal.Decimal:
103 """
104 Pydal type is decimal, Python type is Decimal.
105 """
106 kw["type"] = f"decimal({n}, {m})"
107 return TypedField(decimal.Decimal, **kw)
110Decimal = DecimalField
113def DateField(**kw: typing.Any) -> dt.date:
114 """
115 Pydal type is date, Python type is datetime.date.
116 """
117 kw["type"] = "date"
118 return TypedField(dt.date, **kw)
121Date = DateField
124def TimeField(**kw: typing.Any) -> dt.time:
125 """
126 Pydal type is time, Python type is datetime.time.
127 """
128 kw["type"] = "time"
129 return TypedField(dt.time, **kw)
132Time = TimeField
135def DatetimeField(**kw: typing.Any) -> dt.datetime:
136 """
137 Pydal type is datetime, Python type is datetime.datetime.
138 """
139 kw["type"] = "datetime"
140 return TypedField(dt.datetime, **kw)
143Datetime = DatetimeField
146def PasswordField(**kw: typing.Any) -> str:
147 """
148 Pydal type is password, Python type is str.
149 """
150 kw["type"] = "password"
151 return TypedField(str, **kw)
154Password = PasswordField
157def UploadField(**kw: typing.Any) -> str:
158 """
159 Pydal type is upload, Python type is str.
160 """
161 kw["type"] = "upload"
162 return TypedField(str, **kw)
165Upload = UploadField
167T_subclass = typing.TypeVar("T_subclass", TypedTable, Table)
170def ReferenceField(other_table: str | TypedTable | Table | T_subclass, **kw: typing.Any) -> int:
171 """
172 Pydal type is reference, Python type is int (id).
173 """
174 if isinstance(other_table, str):
175 kw["type"] = f"reference {other_table}"
176 elif isinstance(other_table, Table):
177 # db.table
178 kw["type"] = f"reference {other_table._tablename}"
179 elif issubclass(type(other_table), type) and issubclass(other_table, TypedTable):
180 # SomeTable
181 snakename = TypeDAL._to_snake(other_table.__name__)
182 kw["type"] = f"reference {snakename}"
183 else:
184 raise ValueError(f"Don't know what to do with {type(other_table)}")
186 return TypedField(int, **kw)
189Reference = ReferenceField
192def ListStringField(**kw: typing.Any) -> list[str]:
193 """
194 Pydal type is list:string, Python type is list of str.
195 """
196 kw["type"] = "list:string"
197 return TypedField(list[str], **kw)
200ListString = ListStringField
203def ListIntegerField(**kw: typing.Any) -> list[int]:
204 """
205 Pydal type is list:integer, Python type is list of int.
206 """
207 kw["type"] = "list:integer"
208 return TypedField(list[int], **kw)
211ListInteger = ListIntegerField
214def ListReferenceField(other_table: str, **kw: typing.Any) -> list[int]:
215 """
216 Pydal type is list:reference, Python type is list of int (id).
217 """
218 kw["type"] = f"list:reference {other_table}"
219 return TypedField(list[int], **kw)
222ListReference = ListReferenceField
225def JSONField(**kw: typing.Any) -> object:
226 """
227 Pydal type is json, Python type is object (can be anything JSON-encodable).
228 """
229 kw["type"] = "json"
230 return TypedField(object, **kw)
233def BigintField(**kw: typing.Any) -> int:
234 """
235 Pydal type is bigint, Python type is int.
236 """
237 kw["type"] = "bigint"
238 return TypedField(int, **kw)
241Bigint = BigintField