plain.models 0.49.1__py3-none-any.whl → 0.50.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 (105) hide show
  1. plain/models/CHANGELOG.md +23 -0
  2. plain/models/aggregates.py +42 -19
  3. plain/models/backends/base/base.py +125 -105
  4. plain/models/backends/base/client.py +11 -3
  5. plain/models/backends/base/creation.py +22 -12
  6. plain/models/backends/base/features.py +10 -4
  7. plain/models/backends/base/introspection.py +29 -16
  8. plain/models/backends/base/operations.py +187 -91
  9. plain/models/backends/base/schema.py +267 -165
  10. plain/models/backends/base/validation.py +12 -3
  11. plain/models/backends/ddl_references.py +85 -43
  12. plain/models/backends/mysql/base.py +29 -26
  13. plain/models/backends/mysql/client.py +7 -2
  14. plain/models/backends/mysql/compiler.py +12 -3
  15. plain/models/backends/mysql/creation.py +5 -2
  16. plain/models/backends/mysql/features.py +24 -22
  17. plain/models/backends/mysql/introspection.py +22 -13
  18. plain/models/backends/mysql/operations.py +106 -39
  19. plain/models/backends/mysql/schema.py +48 -24
  20. plain/models/backends/mysql/validation.py +13 -6
  21. plain/models/backends/postgresql/base.py +41 -34
  22. plain/models/backends/postgresql/client.py +7 -2
  23. plain/models/backends/postgresql/creation.py +10 -5
  24. plain/models/backends/postgresql/introspection.py +15 -8
  25. plain/models/backends/postgresql/operations.py +109 -42
  26. plain/models/backends/postgresql/schema.py +85 -46
  27. plain/models/backends/sqlite3/_functions.py +151 -115
  28. plain/models/backends/sqlite3/base.py +37 -23
  29. plain/models/backends/sqlite3/client.py +7 -1
  30. plain/models/backends/sqlite3/creation.py +9 -5
  31. plain/models/backends/sqlite3/features.py +5 -3
  32. plain/models/backends/sqlite3/introspection.py +32 -16
  33. plain/models/backends/sqlite3/operations.py +125 -42
  34. plain/models/backends/sqlite3/schema.py +82 -58
  35. plain/models/backends/utils.py +52 -29
  36. plain/models/backups/cli.py +8 -6
  37. plain/models/backups/clients.py +16 -7
  38. plain/models/backups/core.py +24 -13
  39. plain/models/base.py +113 -74
  40. plain/models/cli.py +94 -63
  41. plain/models/config.py +1 -1
  42. plain/models/connections.py +23 -7
  43. plain/models/constraints.py +65 -47
  44. plain/models/database_url.py +1 -1
  45. plain/models/db.py +6 -2
  46. plain/models/deletion.py +66 -43
  47. plain/models/entrypoints.py +1 -1
  48. plain/models/enums.py +22 -11
  49. plain/models/exceptions.py +23 -8
  50. plain/models/expressions.py +440 -257
  51. plain/models/fields/__init__.py +253 -202
  52. plain/models/fields/json.py +120 -54
  53. plain/models/fields/mixins.py +12 -8
  54. plain/models/fields/related.py +284 -252
  55. plain/models/fields/related_descriptors.py +34 -25
  56. plain/models/fields/related_lookups.py +23 -11
  57. plain/models/fields/related_managers.py +81 -47
  58. plain/models/fields/reverse_related.py +58 -55
  59. plain/models/forms.py +89 -63
  60. plain/models/functions/comparison.py +71 -18
  61. plain/models/functions/datetime.py +79 -29
  62. plain/models/functions/math.py +43 -10
  63. plain/models/functions/mixins.py +24 -7
  64. plain/models/functions/text.py +104 -25
  65. plain/models/functions/window.py +12 -6
  66. plain/models/indexes.py +52 -28
  67. plain/models/lookups.py +228 -153
  68. plain/models/migrations/autodetector.py +86 -43
  69. plain/models/migrations/exceptions.py +7 -3
  70. plain/models/migrations/executor.py +33 -7
  71. plain/models/migrations/graph.py +79 -50
  72. plain/models/migrations/loader.py +45 -22
  73. plain/models/migrations/migration.py +23 -18
  74. plain/models/migrations/operations/base.py +37 -19
  75. plain/models/migrations/operations/fields.py +89 -42
  76. plain/models/migrations/operations/models.py +245 -143
  77. plain/models/migrations/operations/special.py +82 -25
  78. plain/models/migrations/optimizer.py +7 -2
  79. plain/models/migrations/questioner.py +58 -31
  80. plain/models/migrations/recorder.py +18 -11
  81. plain/models/migrations/serializer.py +50 -39
  82. plain/models/migrations/state.py +220 -133
  83. plain/models/migrations/utils.py +29 -13
  84. plain/models/migrations/writer.py +17 -14
  85. plain/models/options.py +63 -56
  86. plain/models/otel.py +16 -6
  87. plain/models/preflight.py +35 -12
  88. plain/models/query.py +323 -228
  89. plain/models/query_utils.py +93 -58
  90. plain/models/registry.py +34 -16
  91. plain/models/sql/compiler.py +146 -97
  92. plain/models/sql/datastructures.py +38 -25
  93. plain/models/sql/query.py +255 -169
  94. plain/models/sql/subqueries.py +32 -21
  95. plain/models/sql/where.py +54 -29
  96. plain/models/test/pytest.py +15 -11
  97. plain/models/test/utils.py +4 -2
  98. plain/models/transaction.py +20 -7
  99. plain/models/utils.py +13 -5
  100. {plain_models-0.49.1.dist-info → plain_models-0.50.0.dist-info}/METADATA +1 -1
  101. plain_models-0.50.0.dist-info/RECORD +122 -0
  102. plain_models-0.49.1.dist-info/RECORD +0 -122
  103. {plain_models-0.49.1.dist-info → plain_models-0.50.0.dist-info}/WHEEL +0 -0
  104. {plain_models-0.49.1.dist-info → plain_models-0.50.0.dist-info}/entry_points.txt +0 -0
  105. {plain_models-0.49.1.dist-info → plain_models-0.50.0.dist-info}/licenses/LICENSE +0 -0
plain/models/preflight.py CHANGED
@@ -1,8 +1,12 @@
1
+ from __future__ import annotations
2
+
1
3
  import inspect
2
4
  from collections import defaultdict
5
+ from collections.abc import Callable
6
+ from typing import Any
3
7
 
4
8
  from plain.models.db import db_connection
5
- from plain.models.registry import models_registry
9
+ from plain.models.registry import ModelsRegistry, models_registry
6
10
  from plain.packages import packages_registry
7
11
  from plain.preflight import PreflightCheck, PreflightResult, register_check
8
12
 
@@ -11,7 +15,7 @@ from plain.preflight import PreflightCheck, PreflightResult, register_check
11
15
  class CheckDatabaseBackends(PreflightCheck):
12
16
  """Validates database backend configuration when plain.models is available."""
13
17
 
14
- def run(self):
18
+ def run(self) -> list[PreflightResult]:
15
19
  return db_connection.validation.preflight()
16
20
 
17
21
 
@@ -19,7 +23,7 @@ class CheckDatabaseBackends(PreflightCheck):
19
23
  class CheckAllModels(PreflightCheck):
20
24
  """Validates all model definitions for common issues."""
21
25
 
22
- def run(self):
26
+ def run(self) -> list[PreflightResult]:
23
27
  db_table_models = defaultdict(list)
24
28
  indexes = defaultdict(list)
25
29
  constraints = defaultdict(list)
@@ -84,7 +88,9 @@ class CheckAllModels(PreflightCheck):
84
88
  return errors
85
89
 
86
90
 
87
- def _check_lazy_references(models_registry, packages_registry):
91
+ def _check_lazy_references(
92
+ models_registry: ModelsRegistry, packages_registry: Any
93
+ ) -> list[PreflightResult]:
88
94
  """
89
95
  Ensure all lazy (i.e. string) model references have been resolved.
90
96
 
@@ -98,7 +104,9 @@ def _check_lazy_references(models_registry, packages_registry):
98
104
  if not pending_models:
99
105
  return []
100
106
 
101
- def extract_operation(obj):
107
+ def extract_operation(
108
+ obj: Any,
109
+ ) -> tuple[Callable[..., Any], list[Any], dict[str, Any]]:
102
110
  """
103
111
  Take a callable found in Packages._pending_operations and identify the
104
112
  original callable passed to Packages.lazy_model_operation(). If that
@@ -115,7 +123,7 @@ def _check_lazy_references(models_registry, packages_registry):
115
123
  operation = operation.func
116
124
  return operation, args, keywords
117
125
 
118
- def app_model_error(model_key):
126
+ def app_model_error(model_key: tuple[str, str]) -> str:
119
127
  try:
120
128
  packages_registry.get_package_config(model_key[0])
121
129
  model_error = "app '{}' doesn't provide model '{}'".format(*model_key)
@@ -129,7 +137,12 @@ def _check_lazy_references(models_registry, packages_registry):
129
137
  # pair, the original lazy function, and its positional and keyword args as
130
138
  # determined by extract_operation().
131
139
 
132
- def field_error(model_key, func, args, keywords):
140
+ def field_error(
141
+ model_key: tuple[str, str],
142
+ func: Callable[..., Any],
143
+ args: list[Any],
144
+ keywords: dict[str, Any],
145
+ ) -> PreflightResult:
133
146
  error_msg = (
134
147
  "The field %(field)s was declared with a lazy reference "
135
148
  "to '%(model)s', but %(model_error)s."
@@ -145,7 +158,12 @@ def _check_lazy_references(models_registry, packages_registry):
145
158
  id="fields.lazy_reference_not_resolvable",
146
159
  )
147
160
 
148
- def default_error(model_key, func, args, keywords):
161
+ def default_error(
162
+ model_key: tuple[str, str],
163
+ func: Callable[..., Any],
164
+ args: list[Any],
165
+ keywords: dict[str, Any],
166
+ ) -> PreflightResult:
149
167
  error_msg = (
150
168
  "%(op)s contains a lazy reference to %(model)s, but %(model_error)s."
151
169
  )
@@ -167,8 +185,13 @@ def _check_lazy_references(models_registry, packages_registry):
167
185
  ("plain.models.fields.related", "resolve_related_class"): field_error,
168
186
  }
169
187
 
170
- def build_error(model_key, func, args, keywords):
171
- key = (func.__module__, func.__name__)
188
+ def build_error(
189
+ model_key: tuple[str, str],
190
+ func: Callable[..., Any],
191
+ args: list[Any],
192
+ keywords: dict[str, Any],
193
+ ) -> PreflightResult | None:
194
+ key = (func.__module__, func.__name__) # type: ignore[attr-defined]
172
195
  error_fn = known_lazy.get(key, default_error)
173
196
  return error_fn(model_key, func, args, keywords) if error_fn else None
174
197
 
@@ -189,7 +212,7 @@ def _check_lazy_references(models_registry, packages_registry):
189
212
  class CheckLazyReferences(PreflightCheck):
190
213
  """Ensures all lazy (string) model references have been resolved."""
191
214
 
192
- def run(self):
215
+ def run(self) -> list[PreflightResult]:
193
216
  return _check_lazy_references(models_registry, packages_registry)
194
217
 
195
218
 
@@ -197,7 +220,7 @@ class CheckLazyReferences(PreflightCheck):
197
220
  class CheckDatabaseTables(PreflightCheck):
198
221
  """Checks for unknown tables in the database when plain.models is available."""
199
222
 
200
- def run(self):
223
+ def run(self) -> list[PreflightResult]:
201
224
  errors = []
202
225
 
203
226
  db_tables = db_connection.introspection.table_names()