plain.models 0.49.2__py3-none-any.whl → 0.51.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 (108) hide show
  1. plain/models/CHANGELOG.md +27 -0
  2. plain/models/README.md +26 -42
  3. plain/models/__init__.py +2 -0
  4. plain/models/aggregates.py +42 -19
  5. plain/models/backends/base/base.py +125 -105
  6. plain/models/backends/base/client.py +11 -3
  7. plain/models/backends/base/creation.py +24 -14
  8. plain/models/backends/base/features.py +10 -4
  9. plain/models/backends/base/introspection.py +37 -20
  10. plain/models/backends/base/operations.py +187 -91
  11. plain/models/backends/base/schema.py +338 -218
  12. plain/models/backends/base/validation.py +13 -4
  13. plain/models/backends/ddl_references.py +85 -43
  14. plain/models/backends/mysql/base.py +29 -26
  15. plain/models/backends/mysql/client.py +7 -2
  16. plain/models/backends/mysql/compiler.py +13 -4
  17. plain/models/backends/mysql/creation.py +5 -2
  18. plain/models/backends/mysql/features.py +24 -22
  19. plain/models/backends/mysql/introspection.py +22 -13
  20. plain/models/backends/mysql/operations.py +107 -40
  21. plain/models/backends/mysql/schema.py +52 -28
  22. plain/models/backends/mysql/validation.py +13 -6
  23. plain/models/backends/postgresql/base.py +41 -34
  24. plain/models/backends/postgresql/client.py +7 -2
  25. plain/models/backends/postgresql/creation.py +10 -5
  26. plain/models/backends/postgresql/introspection.py +15 -8
  27. plain/models/backends/postgresql/operations.py +110 -43
  28. plain/models/backends/postgresql/schema.py +88 -49
  29. plain/models/backends/sqlite3/_functions.py +151 -115
  30. plain/models/backends/sqlite3/base.py +37 -23
  31. plain/models/backends/sqlite3/client.py +7 -1
  32. plain/models/backends/sqlite3/creation.py +9 -5
  33. plain/models/backends/sqlite3/features.py +5 -3
  34. plain/models/backends/sqlite3/introspection.py +32 -16
  35. plain/models/backends/sqlite3/operations.py +126 -43
  36. plain/models/backends/sqlite3/schema.py +127 -92
  37. plain/models/backends/utils.py +52 -29
  38. plain/models/backups/cli.py +8 -6
  39. plain/models/backups/clients.py +16 -7
  40. plain/models/backups/core.py +24 -13
  41. plain/models/base.py +221 -229
  42. plain/models/cli.py +98 -67
  43. plain/models/config.py +1 -1
  44. plain/models/connections.py +23 -7
  45. plain/models/constraints.py +79 -56
  46. plain/models/database_url.py +1 -1
  47. plain/models/db.py +6 -2
  48. plain/models/deletion.py +80 -56
  49. plain/models/entrypoints.py +1 -1
  50. plain/models/enums.py +22 -11
  51. plain/models/exceptions.py +23 -8
  52. plain/models/expressions.py +441 -258
  53. plain/models/fields/__init__.py +272 -217
  54. plain/models/fields/json.py +123 -57
  55. plain/models/fields/mixins.py +12 -8
  56. plain/models/fields/related.py +324 -290
  57. plain/models/fields/related_descriptors.py +33 -24
  58. plain/models/fields/related_lookups.py +24 -12
  59. plain/models/fields/related_managers.py +102 -79
  60. plain/models/fields/reverse_related.py +66 -63
  61. plain/models/forms.py +101 -75
  62. plain/models/functions/comparison.py +71 -18
  63. plain/models/functions/datetime.py +79 -29
  64. plain/models/functions/math.py +43 -10
  65. plain/models/functions/mixins.py +24 -7
  66. plain/models/functions/text.py +104 -25
  67. plain/models/functions/window.py +12 -6
  68. plain/models/indexes.py +57 -32
  69. plain/models/lookups.py +228 -153
  70. plain/models/meta.py +505 -0
  71. plain/models/migrations/autodetector.py +86 -43
  72. plain/models/migrations/exceptions.py +7 -3
  73. plain/models/migrations/executor.py +33 -7
  74. plain/models/migrations/graph.py +79 -50
  75. plain/models/migrations/loader.py +45 -22
  76. plain/models/migrations/migration.py +23 -18
  77. plain/models/migrations/operations/base.py +38 -20
  78. plain/models/migrations/operations/fields.py +95 -48
  79. plain/models/migrations/operations/models.py +246 -142
  80. plain/models/migrations/operations/special.py +82 -25
  81. plain/models/migrations/optimizer.py +7 -2
  82. plain/models/migrations/questioner.py +58 -31
  83. plain/models/migrations/recorder.py +27 -16
  84. plain/models/migrations/serializer.py +50 -39
  85. plain/models/migrations/state.py +232 -156
  86. plain/models/migrations/utils.py +30 -14
  87. plain/models/migrations/writer.py +17 -14
  88. plain/models/options.py +189 -518
  89. plain/models/otel.py +16 -6
  90. plain/models/preflight.py +42 -17
  91. plain/models/query.py +400 -251
  92. plain/models/query_utils.py +109 -69
  93. plain/models/registry.py +40 -21
  94. plain/models/sql/compiler.py +190 -127
  95. plain/models/sql/datastructures.py +38 -25
  96. plain/models/sql/query.py +320 -225
  97. plain/models/sql/subqueries.py +36 -25
  98. plain/models/sql/where.py +54 -29
  99. plain/models/test/pytest.py +15 -11
  100. plain/models/test/utils.py +4 -2
  101. plain/models/transaction.py +20 -7
  102. plain/models/utils.py +17 -6
  103. {plain_models-0.49.2.dist-info → plain_models-0.51.0.dist-info}/METADATA +27 -43
  104. plain_models-0.51.0.dist-info/RECORD +123 -0
  105. plain_models-0.49.2.dist-info/RECORD +0 -122
  106. {plain_models-0.49.2.dist-info → plain_models-0.51.0.dist-info}/WHEEL +0 -0
  107. {plain_models-0.49.2.dist-info → plain_models-0.51.0.dist-info}/entry_points.txt +0 -0
  108. {plain_models-0.49.2.dist-info → plain_models-0.51.0.dist-info}/licenses/LICENSE +0 -0
@@ -1,30 +1,39 @@
1
+ from __future__ import annotations
2
+
1
3
  import datetime
2
4
  import re
3
5
  from collections import namedtuple
6
+ from collections.abc import Generator
7
+ from typing import TYPE_CHECKING, Any
4
8
 
5
9
  from plain.models.fields.related import RECURSIVE_RELATIONSHIP_CONSTANT
6
10
 
11
+ if TYPE_CHECKING:
12
+ from plain.models.fields import Field
13
+
7
14
  FieldReference = namedtuple("FieldReference", "to through")
8
15
 
9
16
  COMPILED_REGEX_TYPE = type(re.compile(""))
10
17
 
11
18
 
12
19
  class RegexObject:
13
- def __init__(self, obj):
20
+ def __init__(self, obj: Any) -> None:
14
21
  self.pattern = obj.pattern
15
22
  self.flags = obj.flags
16
23
 
17
- def __eq__(self, other):
24
+ def __eq__(self, other: Any) -> bool:
18
25
  if not isinstance(other, RegexObject):
19
26
  return NotImplemented
20
27
  return self.pattern == other.pattern and self.flags == other.flags
21
28
 
22
29
 
23
- def get_migration_name_timestamp():
30
+ def get_migration_name_timestamp() -> str:
24
31
  return datetime.datetime.now().strftime("%Y%m%d_%H%M")
25
32
 
26
33
 
27
- def resolve_relation(model, package_label=None, model_name=None):
34
+ def resolve_relation(
35
+ model: str | Any, package_label: str | None = None, model_name: str | None = None
36
+ ) -> tuple[str, str]:
28
37
  """
29
38
  Turn a model class or model reference string and return a model tuple.
30
39
 
@@ -47,16 +56,16 @@ def resolve_relation(model, package_label=None, model_name=None):
47
56
  "package_label must be provided to resolve unscoped model relationships."
48
57
  )
49
58
  return package_label, model.lower()
50
- return model._meta.package_label, model._meta.model_name
59
+ return model.model_options.package_label, model.model_options.model_name
51
60
 
52
61
 
53
62
  def field_references(
54
- model_tuple,
55
- field,
56
- reference_model_tuple,
57
- reference_field_name=None,
58
- reference_field=None,
59
- ):
63
+ model_tuple: tuple[str, str],
64
+ field: Field,
65
+ reference_model_tuple: tuple[str, str],
66
+ reference_field_name: str | None = None,
67
+ reference_field: Field | None = None,
68
+ ) -> FieldReference | bool:
60
69
  """
61
70
  Return either False or a FieldReference if `field` references provided
62
71
  context.
@@ -97,7 +106,9 @@ def field_references(
97
106
  return FieldReference(references_to, references_through)
98
107
 
99
108
 
100
- def get_references(state, model_tuple, field_tuple=()):
109
+ def get_references(
110
+ state: Any, model_tuple: tuple[str, str], field_tuple: tuple[Any, ...] = ()
111
+ ) -> Generator[tuple[Any, str, Field, FieldReference], None, None]:
101
112
  """
102
113
  Generator of (model_state, name, field, reference) referencing
103
114
  provided context.
@@ -108,12 +119,17 @@ def get_references(state, model_tuple, field_tuple=()):
108
119
  for state_model_tuple, model_state in state.models.items():
109
120
  for name, field in model_state.fields.items():
110
121
  reference = field_references(
111
- state_model_tuple, field, model_tuple, *field_tuple
122
+ state_model_tuple,
123
+ field,
124
+ model_tuple,
125
+ *field_tuple, # type: ignore[arg-type]
112
126
  )
113
127
  if reference:
114
128
  yield model_state, name, field, reference
115
129
 
116
130
 
117
- def field_is_referenced(state, model_tuple, field_tuple):
131
+ def field_is_referenced(
132
+ state: Any, model_tuple: tuple[str, str], field_tuple: tuple[Any, ...]
133
+ ) -> bool:
118
134
  """Return whether `field_tuple` is referenced by any state models."""
119
135
  return next(get_references(state, model_tuple, field_tuple), None) is not None
@@ -1,6 +1,9 @@
1
+ from __future__ import annotations
2
+
1
3
  import os
2
4
  import re
3
5
  from importlib import import_module
6
+ from typing import Any
4
7
 
5
8
  from plain.models import migrations
6
9
  from plain.models.migrations.loader import MigrationLoader
@@ -14,13 +17,13 @@ from plain.utils.timezone import now
14
17
 
15
18
 
16
19
  class OperationWriter:
17
- def __init__(self, operation, indentation=2):
20
+ def __init__(self, operation: Any, indentation: int = 2) -> None:
18
21
  self.operation = operation
19
- self.buff = []
22
+ self.buff: list[str] = []
20
23
  self.indentation = indentation
21
24
 
22
- def serialize(self):
23
- def _write(_arg_name, _arg_value):
25
+ def serialize(self) -> tuple[str, set[str]]:
26
+ def _write(_arg_name: str, _arg_value: Any) -> None:
24
27
  if _arg_name in self.operation.serialization_expand_args and isinstance(
25
28
  _arg_value, list | tuple | dict
26
29
  ):
@@ -100,16 +103,16 @@ class OperationWriter:
100
103
  self.feed("),")
101
104
  return self.render(), imports
102
105
 
103
- def indent(self):
106
+ def indent(self) -> None:
104
107
  self.indentation += 1
105
108
 
106
- def unindent(self):
109
+ def unindent(self) -> None:
107
110
  self.indentation -= 1
108
111
 
109
- def feed(self, line):
112
+ def feed(self, line: str) -> None:
110
113
  self.buff.append(" " * (self.indentation * 4) + line)
111
114
 
112
- def render(self):
115
+ def render(self) -> str:
113
116
  return "\n".join(self.buff)
114
117
 
115
118
 
@@ -119,12 +122,12 @@ class MigrationWriter:
119
122
  of the migration file from it.
120
123
  """
121
124
 
122
- def __init__(self, migration, include_header=True):
125
+ def __init__(self, migration: Any, include_header: bool = True) -> None:
123
126
  self.migration = migration
124
127
  self.include_header = include_header
125
128
  self.needs_manual_porting = False
126
129
 
127
- def as_string(self):
130
+ def as_string(self) -> str:
128
131
  """Return a string of the file contents."""
129
132
  items = {
130
133
  "replaces_str": "",
@@ -198,7 +201,7 @@ class MigrationWriter:
198
201
  return MIGRATION_TEMPLATE % items
199
202
 
200
203
  @property
201
- def basedir(self):
204
+ def basedir(self) -> str:
202
205
  migrations_package_name, _ = MigrationLoader.migrations_module(
203
206
  self.migration.package_label
204
207
  )
@@ -266,15 +269,15 @@ class MigrationWriter:
266
269
  return final_dir
267
270
 
268
271
  @property
269
- def filename(self):
272
+ def filename(self) -> str:
270
273
  return f"{self.migration.name}.py"
271
274
 
272
275
  @property
273
- def path(self):
276
+ def path(self) -> str:
274
277
  return os.path.join(self.basedir, self.filename)
275
278
 
276
279
  @classmethod
277
- def serialize(cls, value):
280
+ def serialize(cls, value: Any) -> tuple[str, set[str]]:
278
281
  return serializer_factory(value).serialize()
279
282
 
280
283