piccolo 1.27.1__py3-none-any.whl → 1.28.0__py3-none-any.whl

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 (122) hide show
  1. piccolo/__init__.py +1 -1
  2. piccolo/apps/app/commands/new.py +3 -3
  3. piccolo/apps/asgi/commands/new.py +1 -2
  4. piccolo/apps/fixtures/commands/dump.py +8 -8
  5. piccolo/apps/fixtures/commands/load.py +5 -5
  6. piccolo/apps/fixtures/commands/shared.py +9 -9
  7. piccolo/apps/migrations/auto/diffable_table.py +12 -12
  8. piccolo/apps/migrations/auto/migration_manager.py +59 -66
  9. piccolo/apps/migrations/auto/operations.py +14 -14
  10. piccolo/apps/migrations/auto/schema_differ.py +35 -34
  11. piccolo/apps/migrations/auto/schema_snapshot.py +3 -4
  12. piccolo/apps/migrations/auto/serialisation.py +27 -24
  13. piccolo/apps/migrations/auto/serialisation_legacy.py +2 -2
  14. piccolo/apps/migrations/commands/backwards.py +1 -2
  15. piccolo/apps/migrations/commands/base.py +12 -12
  16. piccolo/apps/migrations/commands/check.py +2 -3
  17. piccolo/apps/migrations/commands/clean.py +3 -3
  18. piccolo/apps/migrations/commands/forwards.py +1 -2
  19. piccolo/apps/migrations/commands/new.py +6 -6
  20. piccolo/apps/migrations/tables.py +3 -3
  21. piccolo/apps/playground/commands/run.py +29 -13
  22. piccolo/apps/schema/commands/generate.py +49 -49
  23. piccolo/apps/schema/commands/graph.py +5 -5
  24. piccolo/apps/shell/commands/run.py +1 -2
  25. piccolo/apps/sql_shell/commands/run.py +4 -4
  26. piccolo/apps/tester/commands/run.py +3 -3
  27. piccolo/apps/user/commands/change_permissions.py +6 -6
  28. piccolo/apps/user/commands/create.py +7 -7
  29. piccolo/apps/user/commands/list.py +2 -2
  30. piccolo/apps/user/tables.py +8 -8
  31. piccolo/columns/base.py +84 -52
  32. piccolo/columns/choices.py +2 -2
  33. piccolo/columns/column_types.py +297 -175
  34. piccolo/columns/combination.py +15 -12
  35. piccolo/columns/defaults/base.py +4 -4
  36. piccolo/columns/defaults/date.py +4 -3
  37. piccolo/columns/defaults/interval.py +4 -3
  38. piccolo/columns/defaults/time.py +4 -3
  39. piccolo/columns/defaults/timestamp.py +4 -3
  40. piccolo/columns/defaults/timestamptz.py +4 -3
  41. piccolo/columns/defaults/uuid.py +3 -2
  42. piccolo/columns/m2m.py +28 -35
  43. piccolo/columns/readable.py +4 -3
  44. piccolo/columns/reference.py +9 -9
  45. piccolo/conf/apps.py +53 -54
  46. piccolo/custom_types.py +28 -6
  47. piccolo/engine/base.py +14 -14
  48. piccolo/engine/cockroach.py +5 -4
  49. piccolo/engine/finder.py +2 -2
  50. piccolo/engine/postgres.py +20 -19
  51. piccolo/engine/sqlite.py +23 -22
  52. piccolo/query/base.py +30 -29
  53. piccolo/query/functions/__init__.py +12 -0
  54. piccolo/query/functions/aggregate.py +4 -3
  55. piccolo/query/functions/array.py +151 -0
  56. piccolo/query/functions/base.py +3 -3
  57. piccolo/query/functions/datetime.py +22 -22
  58. piccolo/query/functions/string.py +4 -4
  59. piccolo/query/functions/type_conversion.py +30 -15
  60. piccolo/query/methods/alter.py +47 -46
  61. piccolo/query/methods/count.py +11 -10
  62. piccolo/query/methods/create.py +6 -5
  63. piccolo/query/methods/create_index.py +9 -8
  64. piccolo/query/methods/delete.py +7 -6
  65. piccolo/query/methods/drop_index.py +7 -6
  66. piccolo/query/methods/exists.py +6 -5
  67. piccolo/query/methods/indexes.py +4 -4
  68. piccolo/query/methods/insert.py +21 -14
  69. piccolo/query/methods/objects.py +60 -50
  70. piccolo/query/methods/raw.py +7 -6
  71. piccolo/query/methods/refresh.py +8 -7
  72. piccolo/query/methods/select.py +56 -49
  73. piccolo/query/methods/table_exists.py +5 -5
  74. piccolo/query/methods/update.py +8 -7
  75. piccolo/query/mixins.py +56 -61
  76. piccolo/query/operators/json.py +11 -11
  77. piccolo/query/proxy.py +8 -9
  78. piccolo/querystring.py +14 -15
  79. piccolo/schema.py +10 -10
  80. piccolo/table.py +93 -94
  81. piccolo/table_reflection.py +9 -9
  82. piccolo/testing/model_builder.py +12 -11
  83. piccolo/testing/random_builder.py +2 -2
  84. piccolo/testing/test_case.py +4 -4
  85. piccolo/utils/dictionary.py +3 -3
  86. piccolo/utils/encoding.py +5 -5
  87. piccolo/utils/lazy_loader.py +3 -3
  88. piccolo/utils/list.py +7 -8
  89. piccolo/utils/objects.py +4 -6
  90. piccolo/utils/pydantic.py +21 -24
  91. piccolo/utils/sql_values.py +3 -3
  92. piccolo/utils/sync.py +4 -3
  93. piccolo/utils/warnings.py +1 -2
  94. {piccolo-1.27.1.dist-info → piccolo-1.28.0.dist-info}/METADATA +1 -1
  95. {piccolo-1.27.1.dist-info → piccolo-1.28.0.dist-info}/RECORD +122 -121
  96. tests/apps/fixtures/commands/test_dump_load.py +1 -2
  97. tests/apps/migrations/auto/integration/test_migrations.py +32 -7
  98. tests/apps/migrations/auto/test_migration_manager.py +2 -2
  99. tests/apps/migrations/auto/test_schema_differ.py +22 -23
  100. tests/apps/migrations/commands/test_forwards_backwards.py +3 -3
  101. tests/columns/m2m/base.py +2 -2
  102. tests/columns/test_array.py +176 -10
  103. tests/columns/test_boolean.py +2 -4
  104. tests/columns/test_combination.py +29 -1
  105. tests/columns/test_db_column_name.py +2 -2
  106. tests/engine/test_extra_nodes.py +2 -2
  107. tests/engine/test_pool.py +3 -3
  108. tests/engine/test_transaction.py +4 -4
  109. tests/query/test_freeze.py +4 -4
  110. tests/table/instance/test_get_related.py +2 -2
  111. tests/table/test_alter.py +4 -4
  112. tests/table/test_indexes.py +1 -2
  113. tests/table/test_refresh.py +2 -2
  114. tests/table/test_select.py +58 -0
  115. tests/table/test_update.py +3 -3
  116. tests/testing/test_model_builder.py +1 -2
  117. tests/utils/test_pydantic.py +36 -36
  118. tests/utils/test_table_reflection.py +1 -2
  119. {piccolo-1.27.1.dist-info → piccolo-1.28.0.dist-info}/WHEEL +0 -0
  120. {piccolo-1.27.1.dist-info → piccolo-1.28.0.dist-info}/entry_points.txt +0 -0
  121. {piccolo-1.27.1.dist-info → piccolo-1.28.0.dist-info}/licenses/LICENSE +0 -0
  122. {piccolo-1.27.1.dist-info → piccolo-1.28.0.dist-info}/top_level.txt +0 -0
@@ -1,20 +1,21 @@
1
1
  from __future__ import annotations
2
2
 
3
- import typing as t
3
+ from collections.abc import Sequence
4
+ from typing import TYPE_CHECKING, Union
4
5
 
5
6
  from piccolo.columns.base import Column
6
7
  from piccolo.query.base import Query
7
8
  from piccolo.querystring import QueryString
8
9
 
9
- if t.TYPE_CHECKING: # pragma: no cover
10
+ if TYPE_CHECKING: # pragma: no cover
10
11
  from piccolo.table import Table
11
12
 
12
13
 
13
14
  class DropIndex(Query):
14
15
  def __init__(
15
16
  self,
16
- table: t.Type[Table],
17
- columns: t.Union[t.List[Column], t.List[str]],
17
+ table: type[Table],
18
+ columns: Union[list[Column], list[str]],
18
19
  if_exists: bool = True,
19
20
  **kwargs,
20
21
  ):
@@ -23,13 +24,13 @@ class DropIndex(Query):
23
24
  super().__init__(table, **kwargs)
24
25
 
25
26
  @property
26
- def column_names(self) -> t.List[str]:
27
+ def column_names(self) -> list[str]:
27
28
  return [
28
29
  i._meta.name if isinstance(i, Column) else i for i in self.columns
29
30
  ]
30
31
 
31
32
  @property
32
- def default_querystrings(self) -> t.Sequence[QueryString]:
33
+ def default_querystrings(self) -> Sequence[QueryString]:
33
34
  column_names = self.column_names
34
35
  index_name = self.table._get_index_name(column_names)
35
36
  query = "DROP INDEX"
@@ -1,6 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
- import typing as t
3
+ from collections.abc import Sequence
4
+ from typing import TypeVar, Union
4
5
 
5
6
  from piccolo.custom_types import Combinable, TableInstance
6
7
  from piccolo.query.base import Query
@@ -12,11 +13,11 @@ from piccolo.querystring import QueryString
12
13
  class Exists(Query[TableInstance, bool]):
13
14
  __slots__ = ("where_delegate",)
14
15
 
15
- def __init__(self, table: t.Type[TableInstance], **kwargs):
16
+ def __init__(self, table: type[TableInstance], **kwargs):
16
17
  super().__init__(table, **kwargs)
17
18
  self.where_delegate = WhereDelegate()
18
19
 
19
- def where(self: Self, *where: t.Union[Combinable, QueryString]) -> Self:
20
+ def where(self: Self, *where: Union[Combinable, QueryString]) -> Self:
20
21
  self.where_delegate.where(*where)
21
22
  return self
22
23
 
@@ -25,7 +26,7 @@ class Exists(Query[TableInstance, bool]):
25
26
  return bool(response[0]["exists"])
26
27
 
27
28
  @property
28
- def default_querystrings(self) -> t.Sequence[QueryString]:
29
+ def default_querystrings(self) -> Sequence[QueryString]:
29
30
  select = Select(table=self.table)
30
31
  select.where_delegate._where = self.where_delegate._where
31
32
  return [
@@ -35,4 +36,4 @@ class Exists(Query[TableInstance, bool]):
35
36
  ]
36
37
 
37
38
 
38
- Self = t.TypeVar("Self", bound=Exists)
39
+ Self = TypeVar("Self", bound=Exists)
@@ -1,6 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
- import typing as t
3
+ from collections.abc import Sequence
4
4
 
5
5
  from piccolo.query.base import Query
6
6
  from piccolo.querystring import QueryString
@@ -12,7 +12,7 @@ class Indexes(Query):
12
12
  """
13
13
 
14
14
  @property
15
- def postgres_querystrings(self) -> t.Sequence[QueryString]:
15
+ def postgres_querystrings(self) -> Sequence[QueryString]:
16
16
  return [
17
17
  QueryString(
18
18
  "SELECT indexname AS name FROM pg_indexes "
@@ -22,11 +22,11 @@ class Indexes(Query):
22
22
  ]
23
23
 
24
24
  @property
25
- def cockroach_querystrings(self) -> t.Sequence[QueryString]:
25
+ def cockroach_querystrings(self) -> Sequence[QueryString]:
26
26
  return self.postgres_querystrings
27
27
 
28
28
  @property
29
- def sqlite_querystrings(self) -> t.Sequence[QueryString]:
29
+ def sqlite_querystrings(self) -> Sequence[QueryString]:
30
30
  tablename = self.table._meta.tablename
31
31
  return [QueryString(f"PRAGMA index_list({tablename})")]
32
32
 
@@ -1,6 +1,15 @@
1
1
  from __future__ import annotations
2
2
 
3
- import typing as t
3
+ from collections.abc import Sequence
4
+ from typing import (
5
+ TYPE_CHECKING,
6
+ Any,
7
+ Generic,
8
+ Literal,
9
+ Optional,
10
+ TypeVar,
11
+ Union,
12
+ )
4
13
 
5
14
  from piccolo.custom_types import Combinable, TableInstance
6
15
  from piccolo.query.base import Query
@@ -12,18 +21,18 @@ from piccolo.query.mixins import (
12
21
  )
13
22
  from piccolo.querystring import QueryString
14
23
 
15
- if t.TYPE_CHECKING: # pragma: no cover
24
+ if TYPE_CHECKING: # pragma: no cover
16
25
  from piccolo.columns.base import Column
17
26
  from piccolo.table import Table
18
27
 
19
28
 
20
29
  class Insert(
21
- t.Generic[TableInstance], Query[TableInstance, t.List[t.Dict[str, t.Any]]]
30
+ Generic[TableInstance], Query[TableInstance, list[dict[str, Any]]]
22
31
  ):
23
32
  __slots__ = ("add_delegate", "on_conflict_delegate", "returning_delegate")
24
33
 
25
34
  def __init__(
26
- self, table: t.Type[TableInstance], *instances: TableInstance, **kwargs
35
+ self, table: type[TableInstance], *instances: TableInstance, **kwargs
27
36
  ):
28
37
  super().__init__(table, **kwargs)
29
38
  self.add_delegate = AddDelegate()
@@ -44,14 +53,12 @@ class Insert(
44
53
 
45
54
  def on_conflict(
46
55
  self: Self,
47
- target: t.Optional[t.Union[str, Column, t.Tuple[Column, ...]]] = None,
48
- action: t.Union[
49
- OnConflictAction, t.Literal["DO NOTHING", "DO UPDATE"]
56
+ target: Optional[Union[str, Column, tuple[Column, ...]]] = None,
57
+ action: Union[
58
+ OnConflictAction, Literal["DO NOTHING", "DO UPDATE"]
50
59
  ] = OnConflictAction.do_nothing,
51
- values: t.Optional[
52
- t.Sequence[t.Union[Column, t.Tuple[Column, t.Any]]]
53
- ] = None,
54
- where: t.Optional[Combinable] = None,
60
+ values: Optional[Sequence[Union[Column, tuple[Column, Any]]]] = None,
61
+ where: Optional[Combinable] = None,
55
62
  ) -> Self:
56
63
  if (
57
64
  self.engine_type == "sqlite"
@@ -81,7 +88,7 @@ class Insert(
81
88
 
82
89
  ###########################################################################
83
90
 
84
- def _raw_response_callback(self, results: t.List):
91
+ def _raw_response_callback(self, results: list):
85
92
  """
86
93
  Assign the ids of the created rows to the model instances.
87
94
  """
@@ -97,7 +104,7 @@ class Insert(
97
104
  table_instance._exists_in_db = True
98
105
 
99
106
  @property
100
- def default_querystrings(self) -> t.Sequence[QueryString]:
107
+ def default_querystrings(self) -> Sequence[QueryString]:
101
108
  base = f"INSERT INTO {self.table._meta.get_formatted_tablename()}"
102
109
  columns = ",".join(
103
110
  f'"{i._meta.db_column_name}"' for i in self.table._meta.columns
@@ -142,4 +149,4 @@ class Insert(
142
149
  return [querystring]
143
150
 
144
151
 
145
- Self = t.TypeVar("Self", bound=Insert)
152
+ Self = TypeVar("Self", bound=Insert)
@@ -1,6 +1,16 @@
1
1
  from __future__ import annotations
2
2
 
3
- import typing as t
3
+ from collections.abc import Callable, Generator, Sequence
4
+ from typing import (
5
+ TYPE_CHECKING,
6
+ Any,
7
+ Generic,
8
+ Literal,
9
+ Optional,
10
+ TypeVar,
11
+ Union,
12
+ cast,
13
+ )
4
14
 
5
15
  from piccolo.columns.column_types import ForeignKey, ReferencedTable
6
16
  from piccolo.columns.combination import And, Where
@@ -27,7 +37,7 @@ from piccolo.querystring import QueryString
27
37
  from piccolo.utils.dictionary import make_nested
28
38
  from piccolo.utils.sync import run_sync
29
39
 
30
- if t.TYPE_CHECKING: # pragma: no cover
40
+ if TYPE_CHECKING: # pragma: no cover
31
41
  from piccolo.columns import Column
32
42
  from piccolo.table import Table
33
43
 
@@ -36,14 +46,14 @@ if t.TYPE_CHECKING: # pragma: no cover
36
46
 
37
47
 
38
48
  class GetOrCreate(
39
- Proxy["Objects[TableInstance]", TableInstance], t.Generic[TableInstance]
49
+ Proxy["Objects[TableInstance]", TableInstance], Generic[TableInstance]
40
50
  ):
41
51
  def __init__(
42
52
  self,
43
53
  query: Objects[TableInstance],
44
- table_class: t.Type[TableInstance],
54
+ table_class: type[TableInstance],
45
55
  where: Combinable,
46
- defaults: t.Dict[Column, t.Any],
56
+ defaults: dict[Column, Any],
47
57
  ):
48
58
  self.query = query
49
59
  self.table_class = table_class
@@ -51,7 +61,7 @@ class GetOrCreate(
51
61
  self.defaults = defaults
52
62
 
53
63
  async def run(
54
- self, node: t.Optional[str] = None, in_pool: bool = True
64
+ self, node: Optional[str] = None, in_pool: bool = True
55
65
  ) -> TableInstance:
56
66
  """
57
67
  :raises ValueError:
@@ -100,32 +110,32 @@ class GetOrCreate(
100
110
  .run()
101
111
  )
102
112
 
103
- instance = t.cast(TableInstance, instance)
113
+ instance = cast(TableInstance, instance)
104
114
  instance._was_created = True
105
115
  return instance
106
116
 
107
117
 
108
118
  class Get(
109
- Proxy["First[TableInstance]", t.Optional[TableInstance]],
110
- t.Generic[TableInstance],
119
+ Proxy["First[TableInstance]", Optional[TableInstance]],
120
+ Generic[TableInstance],
111
121
  ):
112
122
  pass
113
123
 
114
124
 
115
125
  class First(
116
- Proxy["Objects[TableInstance]", t.Optional[TableInstance]],
117
- t.Generic[TableInstance],
126
+ Proxy["Objects[TableInstance]", Optional[TableInstance]],
127
+ Generic[TableInstance],
118
128
  ):
119
129
  async def run(
120
- self, node: t.Optional[str] = None, in_pool: bool = True
121
- ) -> t.Optional[TableInstance]:
130
+ self, node: Optional[str] = None, in_pool: bool = True
131
+ ) -> Optional[TableInstance]:
122
132
  objects = await self.query.run(
123
133
  node=node, in_pool=in_pool, use_callbacks=False
124
134
  )
125
135
 
126
136
  results = objects[0] if objects else None
127
137
 
128
- modified_response: t.Optional[TableInstance] = (
138
+ modified_response: Optional[TableInstance] = (
129
139
  await self.query.callback_delegate.invoke(
130
140
  results=results, kind=CallbackType.success
131
141
  )
@@ -133,7 +143,7 @@ class First(
133
143
  return modified_response
134
144
 
135
145
 
136
- class Create(t.Generic[TableInstance]):
146
+ class Create(Generic[TableInstance]):
137
147
  """
138
148
  This is provided as a simple convenience. Rather than running::
139
149
 
@@ -148,22 +158,22 @@ class Create(t.Generic[TableInstance]):
148
158
 
149
159
  def __init__(
150
160
  self,
151
- table_class: t.Type[TableInstance],
152
- columns: t.Dict[str, t.Any],
161
+ table_class: type[TableInstance],
162
+ columns: dict[str, Any],
153
163
  ):
154
164
  self.table_class = table_class
155
165
  self.columns = columns
156
166
 
157
167
  async def run(
158
168
  self,
159
- node: t.Optional[str] = None,
169
+ node: Optional[str] = None,
160
170
  in_pool: bool = True,
161
171
  ) -> TableInstance:
162
172
  instance = self.table_class(**self.columns)
163
173
  await instance.save().run(node=node, in_pool=in_pool)
164
174
  return instance
165
175
 
166
- def __await__(self) -> t.Generator[None, None, TableInstance]:
176
+ def __await__(self) -> Generator[None, None, TableInstance]:
167
177
  """
168
178
  If the user doesn't explicity call .run(), proxy to it as a
169
179
  convenience.
@@ -179,14 +189,14 @@ class UpdateSelf:
179
189
  def __init__(
180
190
  self,
181
191
  row: Table,
182
- values: t.Dict[t.Union[Column, str], t.Any],
192
+ values: dict[Union[Column, str], Any],
183
193
  ):
184
194
  self.row = row
185
195
  self.values = values
186
196
 
187
197
  async def run(
188
198
  self,
189
- node: t.Optional[str] = None,
199
+ node: Optional[str] = None,
190
200
  in_pool: bool = True,
191
201
  ) -> None:
192
202
  if not self.row._exists_in_db:
@@ -218,7 +228,7 @@ class UpdateSelf:
218
228
  for key, value in response[0].items():
219
229
  setattr(self.row, key, value)
220
230
 
221
- def __await__(self) -> t.Generator[None, None, None]:
231
+ def __await__(self) -> Generator[None, None, None]:
222
232
  """
223
233
  If the user doesn't explicity call .run(), proxy to it as a
224
234
  convenience.
@@ -229,7 +239,7 @@ class UpdateSelf:
229
239
  return run_sync(self.run(*args, **kwargs))
230
240
 
231
241
 
232
- class GetRelated(t.Generic[ReferencedTable]):
242
+ class GetRelated(Generic[ReferencedTable]):
233
243
 
234
244
  def __init__(self, row: Table, foreign_key: ForeignKey[ReferencedTable]):
235
245
  self.row = row
@@ -237,9 +247,9 @@ class GetRelated(t.Generic[ReferencedTable]):
237
247
 
238
248
  async def run(
239
249
  self,
240
- node: t.Optional[str] = None,
250
+ node: Optional[str] = None,
241
251
  in_pool: bool = True,
242
- ) -> t.Optional[ReferencedTable]:
252
+ ) -> Optional[ReferencedTable]:
243
253
  if not self.row._exists_in_db:
244
254
  raise ValueError("The object doesn't exist in the database.")
245
255
 
@@ -264,8 +274,8 @@ class GetRelated(t.Generic[ReferencedTable]):
264
274
  if data is None or not any(data.values()):
265
275
  return None
266
276
 
267
- references = t.cast(
268
- t.Type[ReferencedTable],
277
+ references = cast(
278
+ type[ReferencedTable],
269
279
  self.foreign_key._foreign_key_meta.resolved_references,
270
280
  )
271
281
 
@@ -275,14 +285,14 @@ class GetRelated(t.Generic[ReferencedTable]):
275
285
 
276
286
  def __await__(
277
287
  self,
278
- ) -> t.Generator[None, None, t.Optional[ReferencedTable]]:
288
+ ) -> Generator[None, None, Optional[ReferencedTable]]:
279
289
  """
280
290
  If the user doesn't explicity call .run(), proxy to it as a
281
291
  convenience.
282
292
  """
283
293
  return self.run().__await__()
284
294
 
285
- def run_sync(self, *args, **kwargs) -> t.Optional[ReferencedTable]:
295
+ def run_sync(self, *args, **kwargs) -> Optional[ReferencedTable]:
286
296
  return run_sync(self.run(*args, **kwargs))
287
297
 
288
298
 
@@ -290,7 +300,7 @@ class GetRelated(t.Generic[ReferencedTable]):
290
300
 
291
301
 
292
302
  class Objects(
293
- Query[TableInstance, t.List[TableInstance]], t.Generic[TableInstance]
303
+ Query[TableInstance, list[TableInstance]], Generic[TableInstance]
294
304
  ):
295
305
  """
296
306
  Almost identical to select, except you have to select all fields, and
@@ -312,8 +322,8 @@ class Objects(
312
322
 
313
323
  def __init__(
314
324
  self,
315
- table: t.Type[TableInstance],
316
- prefetch: t.Sequence[t.Union[ForeignKey, t.List[ForeignKey]]] = (),
325
+ table: type[TableInstance],
326
+ prefetch: Sequence[Union[ForeignKey, list[ForeignKey]]] = (),
317
327
  **kwargs,
318
328
  ):
319
329
  super().__init__(table, **kwargs)
@@ -337,7 +347,7 @@ class Objects(
337
347
 
338
348
  def callback(
339
349
  self: Self,
340
- callbacks: t.Union[t.Callable, t.List[t.Callable]],
350
+ callbacks: Union[Callable, list[Callable]],
341
351
  *,
342
352
  on: CallbackType = CallbackType.success,
343
353
  ) -> Self:
@@ -355,7 +365,7 @@ class Objects(
355
365
  return self
356
366
 
357
367
  def prefetch(
358
- self: Self, *fk_columns: t.Union[ForeignKey, t.List[ForeignKey]]
368
+ self: Self, *fk_columns: Union[ForeignKey, list[ForeignKey]]
359
369
  ) -> Self:
360
370
  self.prefetch_delegate.prefetch(*fk_columns)
361
371
  return self
@@ -365,9 +375,9 @@ class Objects(
365
375
  return self
366
376
 
367
377
  def order_by(
368
- self: Self, *columns: t.Union[Column, str, OrderByRaw], ascending=True
378
+ self: Self, *columns: Union[Column, str, OrderByRaw], ascending=True
369
379
  ) -> Self:
370
- _columns: t.List[t.Union[Column, OrderByRaw]] = []
380
+ _columns: list[Union[Column, OrderByRaw]] = []
371
381
  for column in columns:
372
382
  if isinstance(column, str):
373
383
  _columns.append(self.table._meta.get_column_by_name(column))
@@ -377,7 +387,7 @@ class Objects(
377
387
  self.order_by_delegate.order_by(*_columns, ascending=ascending)
378
388
  return self
379
389
 
380
- def where(self: Self, *where: t.Union[Combinable, QueryString]) -> Self:
390
+ def where(self: Self, *where: Union[Combinable, QueryString]) -> Self:
381
391
  self.where_delegate.where(*where)
382
392
  return self
383
393
 
@@ -389,9 +399,9 @@ class Objects(
389
399
 
390
400
  def lock_rows(
391
401
  self: Self,
392
- lock_strength: t.Union[
402
+ lock_strength: Union[
393
403
  LockStrength,
394
- t.Literal[
404
+ Literal[
395
405
  "UPDATE",
396
406
  "NO KEY UPDATE",
397
407
  "KEY SHARE",
@@ -400,7 +410,7 @@ class Objects(
400
410
  ] = LockStrength.update,
401
411
  nowait: bool = False,
402
412
  skip_locked: bool = False,
403
- of: t.Tuple[type[Table], ...] = (),
413
+ of: tuple[type[Table], ...] = (),
404
414
  ) -> Self:
405
415
  self.lock_rows_delegate.lock_rows(
406
416
  lock_strength, nowait, skip_locked, of
@@ -415,7 +425,7 @@ class Objects(
415
425
  def get_or_create(
416
426
  self,
417
427
  where: Combinable,
418
- defaults: t.Optional[t.Dict[Column, t.Any]] = None,
428
+ defaults: Optional[dict[Column, Any]] = None,
419
429
  ) -> GetOrCreate[TableInstance]:
420
430
  if defaults is None:
421
431
  defaults = {}
@@ -423,15 +433,15 @@ class Objects(
423
433
  query=self, table_class=self.table, where=where, defaults=defaults
424
434
  )
425
435
 
426
- def create(self, **columns: t.Any) -> Create[TableInstance]:
436
+ def create(self, **columns: Any) -> Create[TableInstance]:
427
437
  return Create[TableInstance](table_class=self.table, columns=columns)
428
438
 
429
439
  ###########################################################################
430
440
 
431
441
  async def batch(
432
442
  self,
433
- batch_size: t.Optional[int] = None,
434
- node: t.Optional[str] = None,
443
+ batch_size: Optional[int] = None,
444
+ node: Optional[str] = None,
435
445
  **kwargs,
436
446
  ) -> BaseBatch:
437
447
  if batch_size:
@@ -447,7 +457,7 @@ class Objects(
447
457
  return response
448
458
 
449
459
  @property
450
- def default_querystrings(self) -> t.Sequence[QueryString]:
460
+ def default_querystrings(self) -> Sequence[QueryString]:
451
461
  select = Select(table=self.table)
452
462
 
453
463
  for attr in (
@@ -481,17 +491,17 @@ class Objects(
481
491
 
482
492
  async def run(
483
493
  self,
484
- node: t.Optional[str] = None,
494
+ node: Optional[str] = None,
485
495
  in_pool: bool = True,
486
496
  use_callbacks: bool = True,
487
- ) -> t.List[TableInstance]:
497
+ ) -> list[TableInstance]:
488
498
  results = await super().run(node=node, in_pool=in_pool)
489
499
 
490
500
  if use_callbacks:
491
501
  # With callbacks, the user can return any data that they want.
492
502
  # Assume that most of the time they will still return a list of
493
503
  # Table instances.
494
- modified: t.List[TableInstance] = (
504
+ modified: list[TableInstance] = (
495
505
  await self.callback_delegate.invoke(
496
506
  results, kind=CallbackType.success
497
507
  )
@@ -502,8 +512,8 @@ class Objects(
502
512
 
503
513
  def __await__(
504
514
  self,
505
- ) -> t.Generator[None, None, t.List[TableInstance]]:
515
+ ) -> Generator[None, None, list[TableInstance]]:
506
516
  return super().__await__()
507
517
 
508
518
 
509
- Self = t.TypeVar("Self", bound=Objects)
519
+ Self = TypeVar("Self", bound=Objects)
@@ -1,12 +1,13 @@
1
1
  from __future__ import annotations
2
2
 
3
- import typing as t
3
+ from collections.abc import Sequence
4
+ from typing import TYPE_CHECKING, Optional
4
5
 
5
6
  from piccolo.engine.base import BaseBatch
6
7
  from piccolo.query.base import Query
7
8
  from piccolo.querystring import QueryString
8
9
 
9
- if t.TYPE_CHECKING: # pragma: no cover
10
+ if TYPE_CHECKING: # pragma: no cover
10
11
  from piccolo.table import Table
11
12
 
12
13
 
@@ -15,7 +16,7 @@ class Raw(Query):
15
16
 
16
17
  def __init__(
17
18
  self,
18
- table: t.Type[Table],
19
+ table: type[Table],
19
20
  querystring: QueryString = QueryString(""),
20
21
  **kwargs,
21
22
  ):
@@ -24,8 +25,8 @@ class Raw(Query):
24
25
 
25
26
  async def batch(
26
27
  self,
27
- batch_size: t.Optional[int] = None,
28
- node: t.Optional[str] = None,
28
+ batch_size: Optional[int] = None,
29
+ node: Optional[str] = None,
29
30
  **kwargs,
30
31
  ) -> BaseBatch:
31
32
  if batch_size:
@@ -35,5 +36,5 @@ class Raw(Query):
35
36
  return await self.table._meta.db.batch(self, **kwargs)
36
37
 
37
38
  @property
38
- def default_querystrings(self) -> t.Sequence[QueryString]:
39
+ def default_querystrings(self) -> Sequence[QueryString]:
39
40
  return [self.querystring]
@@ -1,11 +1,12 @@
1
1
  from __future__ import annotations
2
2
 
3
- import typing as t
3
+ from collections.abc import Sequence
4
+ from typing import TYPE_CHECKING, Optional
4
5
 
5
6
  from piccolo.utils.encoding import JSONDict
6
7
  from piccolo.utils.sync import run_sync
7
8
 
8
- if t.TYPE_CHECKING: # pragma: no cover
9
+ if TYPE_CHECKING: # pragma: no cover
9
10
  from piccolo.columns import Column
10
11
  from piccolo.table import Table
11
12
 
@@ -30,7 +31,7 @@ class Refresh:
30
31
  def __init__(
31
32
  self,
32
33
  instance: Table,
33
- columns: t.Optional[t.Sequence[Column]] = None,
34
+ columns: Optional[Sequence[Column]] = None,
34
35
  load_json: bool = False,
35
36
  ):
36
37
  self.instance = instance
@@ -50,7 +51,7 @@ class Refresh:
50
51
  self.load_json = load_json
51
52
 
52
53
  @property
53
- def _columns(self) -> t.Sequence[Column]:
54
+ def _columns(self) -> Sequence[Column]:
54
55
  """
55
56
  Works out which columns the user wants to refresh.
56
57
  """
@@ -61,7 +62,7 @@ class Refresh:
61
62
  i for i in self.instance._meta.columns if not i._meta.primary_key
62
63
  ]
63
64
 
64
- def _get_columns(self, instance: Table, columns: t.Sequence[Column]):
65
+ def _get_columns(self, instance: Table, columns: Sequence[Column]):
65
66
  """
66
67
  If `prefetch` was used on the object, for example::
67
68
 
@@ -100,7 +101,7 @@ class Refresh:
100
101
 
101
102
  return select_columns
102
103
 
103
- def _update_instance(self, instance: Table, data_dict: t.Dict):
104
+ def _update_instance(self, instance: Table, data_dict: dict):
104
105
  """
105
106
  Update the table instance. It is called recursively, if the instance
106
107
  has child instances.
@@ -119,7 +120,7 @@ class Refresh:
119
120
  setattr(instance, key, value)
120
121
 
121
122
  async def run(
122
- self, in_pool: bool = True, node: t.Optional[str] = None
123
+ self, in_pool: bool = True, node: Optional[str] = None
123
124
  ) -> Table:
124
125
  """
125
126
  Run it asynchronously. For example::