plain.postgres 0.94.1__tar.gz → 0.94.2__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.
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/.gitignore +1 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/PKG-INFO +2 -2
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/CHANGELOG.md +11 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/agents/.claude/skills/plain-postgres-doctor/SKILL.md +1 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/aggregates.py +2 -2
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/base.py +3 -3
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/cli/migrations.py +2 -4
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/connection.py +3 -3
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/constraints.py +1 -1
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/deletion.py +2 -2
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/enums.py +5 -5
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/expressions.py +5 -5
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/fields/encrypted.py +5 -5
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/fields/related.py +4 -7
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/fields/related_managers.py +1 -1
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/fields/reverse_related.py +3 -3
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/forms.py +1 -1
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/indexes.py +1 -1
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/lookups.py +2 -2
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/meta.py +1 -1
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/migrations/__init__.py +1 -2
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/migrations/autodetector.py +8 -39
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/migrations/graph.py +1 -1
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/migrations/migration.py +0 -17
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/migrations/recorder.py +1 -1
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/migrations/serializer.py +1 -10
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/migrations/state.py +2 -2
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/migrations/utils.py +1 -1
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/migrations/writer.py +2 -9
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/preflight.py +1 -1
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/query.py +9 -9
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/query_utils.py +1 -1
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/sql/compiler.py +11 -11
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/sql/query.py +6 -6
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/test/pytest.py +4 -4
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/utils.py +1 -1
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/pyproject.toml +2 -2
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/tests/test_connection_isolation.py +2 -2
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/tests/test_encrypted_fields.py +1 -1
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/tests/test_exceptions.py +2 -2
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/tests/test_models.py +3 -3
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/tests/test_related_descriptors.py +3 -3
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/CLAUDE.md +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/LICENSE +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/README.md +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/README.md +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/__init__.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/agents/.claude/rules/plain-postgres.md +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/cli/__init__.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/cli/converge.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/cli/core.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/cli/diagnose.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/cli/schema.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/cli/sync.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/config.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/connections.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/constants.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/convergence/__init__.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/convergence/analysis.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/convergence/fixes.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/convergence/planning.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/database_url.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/db.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/ddl.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/default_settings.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/dialect.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/entrypoints.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/exceptions.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/fields/__init__.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/fields/json.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/fields/mixins.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/fields/related_descriptors.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/fields/related_lookups.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/fields/reverse_descriptors.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/fields/timezones.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/functions/__init__.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/functions/comparison.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/functions/datetime.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/functions/math.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/functions/mixins.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/functions/text.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/functions/window.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/introspection/__init__.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/introspection/health.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/introspection/schema.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/migrations/exceptions.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/migrations/executor.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/migrations/loader.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/migrations/operations/__init__.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/migrations/operations/base.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/migrations/operations/fields.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/migrations/operations/models.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/migrations/operations/special.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/migrations/optimizer.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/migrations/questioner.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/options.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/otel.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/registry.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/schema.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/sql/__init__.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/sql/constants.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/sql/datastructures.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/sql/where.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/test/__init__.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/test/utils.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/transaction.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/types.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/plain/postgres/types.pyi +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/tests/app/examples/migrations/0001_initial.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/tests/app/examples/migrations/0002_test_field_removed.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/tests/app/examples/migrations/0003_deleteparent_childsetnull_childsetdefault_and_more.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/tests/app/examples/migrations/0004_defaultquerysetmodel_mixintestmodel_and_more.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/tests/app/examples/migrations/0005_feature_carfeature_car_features.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/tests/app/examples/migrations/0006_secretstore.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/tests/app/examples/migrations/0007_treenode_unconstrainedchild.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/tests/app/examples/migrations/__init__.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/tests/app/examples/models.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/tests/app/settings.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/tests/app/urls.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/tests/conftest_convergence.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/tests/test_connection_lifecycle.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/tests/test_convergence.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/tests/test_convergence_constraints.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/tests/test_convergence_fk.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/tests/test_convergence_indexes.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/tests/test_convergence_nullability.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/tests/test_database_url.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/tests/test_delete_behaviors.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/tests/test_introspection.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/tests/test_iterator.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/tests/test_manager_assignment.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/tests/test_migration_executor.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/tests/test_read_only_transactions.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/tests/test_related_manager_api.py +0 -0
- {plain_postgres-0.94.1 → plain_postgres-0.94.2}/tests/test_schema_normalize_type.py +0 -0
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: plain.postgres
|
|
3
|
-
Version: 0.94.
|
|
3
|
+
Version: 0.94.2
|
|
4
4
|
Summary: Model your data and store it in a database.
|
|
5
5
|
Author-email: Dave Gaeddert <dave.gaeddert@dropseed.dev>
|
|
6
6
|
License-Expression: BSD-3-Clause
|
|
7
7
|
License-File: LICENSE
|
|
8
8
|
Requires-Python: >=3.13
|
|
9
|
-
Requires-Dist: plain<1.0.0,>=0.
|
|
9
|
+
Requires-Dist: plain<1.0.0,>=0.132.0
|
|
10
10
|
Requires-Dist: sqlparse>=0.3.1
|
|
11
11
|
Description-Content-Type: text/markdown
|
|
12
12
|
|
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# plain-postgres changelog
|
|
2
2
|
|
|
3
|
+
## [0.94.2](https://github.com/dropseed/plain/releases/plain-postgres@0.94.2) (2026-04-13)
|
|
4
|
+
|
|
5
|
+
### What's changed
|
|
6
|
+
|
|
7
|
+
- Updated internal references to use the fixed `app.users.models.User` convention. ([0861c9915cb6](https://github.com/dropseed/plain/commit/0861c9915cb6))
|
|
8
|
+
- Migrated type suppression comments to `ty: ignore` for the new ty checker version. ([4ec631a7ef51](https://github.com/dropseed/plain/commit/4ec631a7ef51))
|
|
9
|
+
|
|
10
|
+
### Upgrade instructions
|
|
11
|
+
|
|
12
|
+
- No changes required.
|
|
13
|
+
|
|
3
14
|
## [0.94.1](https://github.com/dropseed/plain/releases/plain-postgres@0.94.1) (2026-04-05)
|
|
4
15
|
|
|
5
16
|
### What's changed
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: plain-postgres-doctor
|
|
3
3
|
description: Check overall database health — schema correctness and operational health. Use when asked to check the database, validate schema, optimize indexes, or diagnose Postgres problems.
|
|
4
|
+
context: fork
|
|
4
5
|
---
|
|
5
6
|
|
|
6
7
|
# Database Doctor
|
|
@@ -75,7 +75,7 @@ class Aggregate(Func):
|
|
|
75
75
|
self.filter = self.filter and exprs_list.pop()
|
|
76
76
|
super().set_source_expressions(exprs_list)
|
|
77
77
|
|
|
78
|
-
def resolve_expression( #
|
|
78
|
+
def resolve_expression( # ty: ignore[invalid-method-override]
|
|
79
79
|
self,
|
|
80
80
|
query: Any = None,
|
|
81
81
|
allow_joins: bool = True,
|
|
@@ -140,7 +140,7 @@ class Aggregate(Func):
|
|
|
140
140
|
if self.filter is not None:
|
|
141
141
|
# Use FILTER clause for aggregates when filter is specified
|
|
142
142
|
try:
|
|
143
|
-
filter_sql, filter_params = self.filter.as_sql(compiler, connection) #
|
|
143
|
+
filter_sql, filter_params = self.filter.as_sql(compiler, connection) # ty: ignore[unresolved-attribute]
|
|
144
144
|
except FullResultSet:
|
|
145
145
|
pass
|
|
146
146
|
else:
|
|
@@ -744,7 +744,7 @@ class Model(metaclass=ModelBase):
|
|
|
744
744
|
|
|
745
745
|
if len(unique_check) == 1:
|
|
746
746
|
field = meta.get_forward_field(unique_check[0])
|
|
747
|
-
params["field_label"] = field.name #
|
|
747
|
+
params["field_label"] = field.name # ty: ignore[invalid-assignment]
|
|
748
748
|
return ValidationError(
|
|
749
749
|
message=field.error_messages["unique"],
|
|
750
750
|
code="unique",
|
|
@@ -1215,7 +1215,7 @@ class Model(metaclass=ModelBase):
|
|
|
1215
1215
|
fld = None
|
|
1216
1216
|
for part in field.split(LOOKUP_SEP):
|
|
1217
1217
|
try:
|
|
1218
|
-
fld = _cls._model_meta.get_field(part) #
|
|
1218
|
+
fld = _cls._model_meta.get_field(part) # ty: ignore[unresolved-attribute]
|
|
1219
1219
|
if isinstance(fld, RelatedField):
|
|
1220
1220
|
_cls = fld.path_infos[-1].to_meta.model
|
|
1221
1221
|
else:
|
|
@@ -1413,4 +1413,4 @@ def model_unpickle(model_id: tuple[str, str] | type[Model]) -> Model:
|
|
|
1413
1413
|
|
|
1414
1414
|
|
|
1415
1415
|
# Pickle protocol marker - functions don't normally have this attribute
|
|
1416
|
-
model_unpickle.__safe_for_unpickle__ = True #
|
|
1416
|
+
model_unpickle.__safe_for_unpickle__ = True # ty: ignore[unresolved-attribute]
|
|
@@ -16,7 +16,7 @@ from ..db import get_connection
|
|
|
16
16
|
from ..migrations.autodetector import MigrationAutodetector
|
|
17
17
|
from ..migrations.executor import MigrationExecutor
|
|
18
18
|
from ..migrations.loader import AmbiguityError, MigrationLoader
|
|
19
|
-
from ..migrations.migration import Migration
|
|
19
|
+
from ..migrations.migration import Migration
|
|
20
20
|
from ..migrations.optimizer import MigrationOptimizer
|
|
21
21
|
from ..migrations.questioner import (
|
|
22
22
|
InteractiveMigrationQuestioner,
|
|
@@ -971,9 +971,7 @@ def squash(
|
|
|
971
971
|
)
|
|
972
972
|
operations.extend(smigration.operations)
|
|
973
973
|
for dependency in smigration.dependencies:
|
|
974
|
-
if
|
|
975
|
-
dependencies.add(dependency)
|
|
976
|
-
elif dependency[0] != smigration.package_label or first_migration:
|
|
974
|
+
if dependency[0] != smigration.package_label or first_migration:
|
|
977
975
|
dependencies.add(dependency)
|
|
978
976
|
first_migration = False
|
|
979
977
|
|
|
@@ -354,7 +354,7 @@ class DatabaseConnection:
|
|
|
354
354
|
return False
|
|
355
355
|
if new_role := self.settings_dict.get("OPTIONS", {}).get("assume_role"):
|
|
356
356
|
sql_str = self.compose_sql("SET ROLE %s", [new_role])
|
|
357
|
-
self.connection.execute(sql_str) #
|
|
357
|
+
self.connection.execute(sql_str) # ty: ignore[invalid-argument-type]
|
|
358
358
|
return True
|
|
359
359
|
return False
|
|
360
360
|
|
|
@@ -373,7 +373,7 @@ class DatabaseConnection:
|
|
|
373
373
|
|
|
374
374
|
# Register the cursor timezone only if the connection disagrees, to avoid copying the adapter map.
|
|
375
375
|
tzloader = self.connection.adapters.get_loader(TIMESTAMPTZ_OID, Format.TEXT)
|
|
376
|
-
if self.timezone != tzloader.timezone: #
|
|
376
|
+
if self.timezone != tzloader.timezone: # ty: ignore[unresolved-attribute]
|
|
377
377
|
register_tzloader(self.timezone, cursor)
|
|
378
378
|
return cursor
|
|
379
379
|
|
|
@@ -1309,7 +1309,7 @@ class CursorMixin:
|
|
|
1309
1309
|
|
|
1310
1310
|
qparts.append(psycopg_sql.SQL(")"))
|
|
1311
1311
|
stmt = psycopg_sql.Composed(qparts)
|
|
1312
|
-
self.execute(stmt) #
|
|
1312
|
+
self.execute(stmt) # ty: ignore[unresolved-attribute]
|
|
1313
1313
|
return args
|
|
1314
1314
|
|
|
1315
1315
|
|
|
@@ -372,7 +372,7 @@ class UniqueConstraint(BaseConstraint):
|
|
|
372
372
|
if exclude:
|
|
373
373
|
for expression in self.expressions:
|
|
374
374
|
if hasattr(expression, "flatten"):
|
|
375
|
-
for expr in expression.flatten(): #
|
|
375
|
+
for expr in expression.flatten(): # ty: ignore[call-non-callable]
|
|
376
376
|
if isinstance(expr, F) and expr.name in exclude:
|
|
377
377
|
return
|
|
378
378
|
elif isinstance(expression, F) and expression.name in exclude:
|
|
@@ -160,7 +160,7 @@ class Collector:
|
|
|
160
160
|
if not objs:
|
|
161
161
|
return []
|
|
162
162
|
new_objs = []
|
|
163
|
-
model = objs[0].__class__ #
|
|
163
|
+
model = objs[0].__class__ # ty: ignore[not-subscriptable]
|
|
164
164
|
instances = self.data[model]
|
|
165
165
|
for obj in objs:
|
|
166
166
|
if obj not in instances:
|
|
@@ -192,7 +192,7 @@ class Collector:
|
|
|
192
192
|
|
|
193
193
|
def add_restricted_objects(self, field: RelatedField, objs: Iterable[Any]) -> None:
|
|
194
194
|
if objs:
|
|
195
|
-
model = objs[0].__class__ #
|
|
195
|
+
model = objs[0].__class__ # ty: ignore[not-subscriptable]
|
|
196
196
|
self.restricted_objects[model][field].update(objs)
|
|
197
197
|
|
|
198
198
|
def clear_restricted_objects_from_set(self, model: Any, objs: set[Any]) -> None:
|
|
@@ -35,26 +35,26 @@ class ChoicesMeta(enum.EnumMeta):
|
|
|
35
35
|
# Use dict.__setitem__() to suppress defenses against double
|
|
36
36
|
# assignment in enum's classdict.
|
|
37
37
|
dict.__setitem__(classdict, key, value)
|
|
38
|
-
cls = super().__new__(metacls, classname, bases, classdict, **kwds) #
|
|
38
|
+
cls = super().__new__(metacls, classname, bases, classdict, **kwds) # ty: ignore[invalid-super-argument]
|
|
39
39
|
for member, label in zip(cls.__members__.values(), labels):
|
|
40
40
|
member._label_ = label
|
|
41
41
|
return enum.unique(cls)
|
|
42
42
|
|
|
43
|
-
def __contains__(cls, member: object) -> bool: #
|
|
43
|
+
def __contains__(cls, member: object) -> bool: # ty: ignore[invalid-method-override]
|
|
44
44
|
if not isinstance(member, enum.Enum):
|
|
45
45
|
# Allow non-enums to match against member values.
|
|
46
|
-
return any(x.value == member for x in cls) #
|
|
46
|
+
return any(x.value == member for x in cls) # ty: ignore[unresolved-attribute]
|
|
47
47
|
return super().__contains__(member)
|
|
48
48
|
|
|
49
49
|
@property
|
|
50
50
|
def names(cls) -> list[str]:
|
|
51
51
|
empty = ["__empty__"] if hasattr(cls, "__empty__") else []
|
|
52
|
-
return empty + [member.name for member in cls] #
|
|
52
|
+
return empty + [member.name for member in cls] # ty: ignore[unresolved-attribute]
|
|
53
53
|
|
|
54
54
|
@property
|
|
55
55
|
def choices(cls) -> list[tuple[Any, str]]:
|
|
56
56
|
empty = [(None, cls.__empty__)] if hasattr(cls, "__empty__") else []
|
|
57
|
-
return empty + [(member.value, member.label) for member in cls] #
|
|
57
|
+
return empty + [(member.value, member.label) for member in cls] # ty: ignore[unresolved-attribute, invalid-return-type]
|
|
58
58
|
|
|
59
59
|
@property
|
|
60
60
|
def labels(cls) -> list[str]:
|
|
@@ -432,7 +432,7 @@ class BaseExpression:
|
|
|
432
432
|
return self.output_field.get_lookup(lookup)
|
|
433
433
|
|
|
434
434
|
def get_transform(self, name: str) -> type[Transform] | None:
|
|
435
|
-
return self.output_field.get_transform(name) #
|
|
435
|
+
return self.output_field.get_transform(name) # ty: ignore[invalid-return-type]
|
|
436
436
|
|
|
437
437
|
def relabeled_clone(self, change_map: dict[str, str]) -> Self:
|
|
438
438
|
clone = self.copy()
|
|
@@ -1045,7 +1045,7 @@ class Value(Expression):
|
|
|
1045
1045
|
else:
|
|
1046
1046
|
val = output_field.get_db_prep_value(val, connection=connection)
|
|
1047
1047
|
if hasattr(output_field, "get_placeholder"):
|
|
1048
|
-
return output_field.get_placeholder(val, compiler, connection), [val] #
|
|
1048
|
+
return output_field.get_placeholder(val, compiler, connection), [val] # ty: ignore[call-non-callable]
|
|
1049
1049
|
if val is None:
|
|
1050
1050
|
return "NULL", []
|
|
1051
1051
|
return "%s", [val]
|
|
@@ -1366,7 +1366,7 @@ class When(Expression):
|
|
|
1366
1366
|
if isinstance(condition, Q) and not condition:
|
|
1367
1367
|
raise ValueError("An empty Q() can't be used as a When() condition.")
|
|
1368
1368
|
super().__init__(output_field=None)
|
|
1369
|
-
self.condition = condition #
|
|
1369
|
+
self.condition = condition # ty: ignore[invalid-assignment]
|
|
1370
1370
|
self.result = self._parse_expressions(then)[0]
|
|
1371
1371
|
|
|
1372
1372
|
def __str__(self) -> str:
|
|
@@ -1703,10 +1703,10 @@ class OrderBy(Expression):
|
|
|
1703
1703
|
self.nulls_last = None
|
|
1704
1704
|
return self
|
|
1705
1705
|
|
|
1706
|
-
def asc(self) -> None: #
|
|
1706
|
+
def asc(self) -> None: # ty: ignore[invalid-method-override]
|
|
1707
1707
|
self.descending = False
|
|
1708
1708
|
|
|
1709
|
-
def desc(self) -> None: #
|
|
1709
|
+
def desc(self) -> None: # ty: ignore[invalid-method-override]
|
|
1710
1710
|
self.descending = True
|
|
1711
1711
|
|
|
1712
1712
|
|
|
@@ -10,11 +10,11 @@ try:
|
|
|
10
10
|
from cryptography.hazmat.primitives import hashes
|
|
11
11
|
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
|
|
12
12
|
except ImportError:
|
|
13
|
-
Fernet = None #
|
|
14
|
-
InvalidToken = None #
|
|
15
|
-
MultiFernet = None #
|
|
16
|
-
hashes = None #
|
|
17
|
-
PBKDF2HMAC = None #
|
|
13
|
+
Fernet = None # ty: ignore[invalid-assignment]
|
|
14
|
+
InvalidToken = None # ty: ignore[invalid-assignment]
|
|
15
|
+
MultiFernet = None # ty: ignore[invalid-assignment]
|
|
16
|
+
hashes = None # ty: ignore[invalid-assignment]
|
|
17
|
+
PBKDF2HMAC = None # ty: ignore[invalid-assignment]
|
|
18
18
|
|
|
19
19
|
from plain import exceptions, preflight
|
|
20
20
|
from plain.runtime import settings
|
|
@@ -11,7 +11,6 @@ from plain.postgres.exceptions import FieldDoesNotExist, FieldError
|
|
|
11
11
|
from plain.postgres.query_utils import PathInfo, Q
|
|
12
12
|
from plain.postgres.utils import make_model_tuple
|
|
13
13
|
from plain.preflight import PreflightResult
|
|
14
|
-
from plain.runtime import SettingsReference
|
|
15
14
|
|
|
16
15
|
from ..registry import models_registry
|
|
17
16
|
from . import Field
|
|
@@ -115,7 +114,7 @@ class RelatedField(FieldCacheMixin, Field):
|
|
|
115
114
|
obj = super().__deepcopy__(memodict)
|
|
116
115
|
obj.remote_field = copy.copy(self.remote_field)
|
|
117
116
|
if hasattr(self.remote_field, "field") and self.remote_field.field is self:
|
|
118
|
-
obj.remote_field.field = obj #
|
|
117
|
+
obj.remote_field.field = obj # ty: ignore[invalid-assignment]
|
|
119
118
|
return obj
|
|
120
119
|
|
|
121
120
|
@cached_property
|
|
@@ -288,7 +287,7 @@ class RelatedField(FieldCacheMixin, Field):
|
|
|
288
287
|
returned.
|
|
289
288
|
"""
|
|
290
289
|
if callable(self.remote_field.limit_choices_to):
|
|
291
|
-
return self.remote_field.limit_choices_to() #
|
|
290
|
+
return self.remote_field.limit_choices_to() # ty: ignore[call-top-callable]
|
|
292
291
|
return self.remote_field.limit_choices_to
|
|
293
292
|
|
|
294
293
|
def related_query_name(self) -> str:
|
|
@@ -543,9 +542,7 @@ class ForeignKeyField(RelatedField):
|
|
|
543
542
|
name, path, args, kwargs = super().deconstruct()
|
|
544
543
|
kwargs["on_delete"] = self.remote_field.on_delete
|
|
545
544
|
|
|
546
|
-
if isinstance(self.remote_field.model,
|
|
547
|
-
kwargs["to"] = self.remote_field.model
|
|
548
|
-
elif isinstance(self.remote_field.model, str):
|
|
545
|
+
if isinstance(self.remote_field.model, str):
|
|
549
546
|
if "." in self.remote_field.model:
|
|
550
547
|
package_label, model_name = self.remote_field.model.split(".")
|
|
551
548
|
kwargs["to"] = f"{package_label}.{model_name.lower()}"
|
|
@@ -1130,7 +1127,7 @@ class ManyToManyField(RelatedField):
|
|
|
1130
1127
|
)
|
|
1131
1128
|
|
|
1132
1129
|
# Add the descriptor for the m2m relation.
|
|
1133
|
-
setattr(cls, self.name, ForwardManyToManyDescriptor(self.remote_field)) #
|
|
1130
|
+
setattr(cls, self.name, ForwardManyToManyDescriptor(self.remote_field)) # ty: ignore[invalid-argument-type]
|
|
1134
1131
|
|
|
1135
1132
|
# Set up the accessor for the m2m table name for the relation.
|
|
1136
1133
|
self.m2m_db_table = self._get_m2m_db_table
|
|
@@ -367,7 +367,7 @@ class ManyToManyManager(BaseRelatedManager[T, QS]):
|
|
|
367
367
|
for lh_field, rh_field in self.source_field.related_fields:
|
|
368
368
|
core_filter_key = f"{self.query_field_name}__{rh_field.name}"
|
|
369
369
|
self.core_filters[core_filter_key] = getattr(instance, rh_field.attname)
|
|
370
|
-
self.id_field_names[lh_field.name] = rh_field.name #
|
|
370
|
+
self.id_field_names[lh_field.name] = rh_field.name # ty: ignore[invalid-assignment]
|
|
371
371
|
|
|
372
372
|
self.related_val = self.source_field.get_foreign_related_value(instance)
|
|
373
373
|
if None in self.related_val:
|
|
@@ -69,10 +69,10 @@ class ForeignObjectRel(FieldCacheMixin):
|
|
|
69
69
|
limit_choices_to: dict[str, Any] | Q | None = None,
|
|
70
70
|
on_delete: OnDeleteCallback | None = None,
|
|
71
71
|
):
|
|
72
|
-
self.field = field #
|
|
72
|
+
self.field = field # ty: ignore[invalid-assignment]
|
|
73
73
|
# Initially may be a string, gets resolved to type[Model] by lazy_related_operation
|
|
74
74
|
# (see related.py:250 where field.remote_field.model is overwritten)
|
|
75
|
-
self.model = to #
|
|
75
|
+
self.model = to # ty: ignore[invalid-assignment]
|
|
76
76
|
self.related_query_name = related_query_name
|
|
77
77
|
self.limit_choices_to = {} if limit_choices_to is None else limit_choices_to
|
|
78
78
|
self.on_delete = on_delete
|
|
@@ -290,7 +290,7 @@ class ManyToManyRel(ForeignObjectRel):
|
|
|
290
290
|
|
|
291
291
|
# Initially may be a string, gets resolved to type[Model] by lazy_related_operation
|
|
292
292
|
# (see related.py:1143 where field.remote_field.through is overwritten)
|
|
293
|
-
self.through = through #
|
|
293
|
+
self.through = through # ty: ignore[invalid-assignment]
|
|
294
294
|
self.through_fields = through_fields
|
|
295
295
|
|
|
296
296
|
self.symmetrical = symmetrical
|
|
@@ -578,7 +578,7 @@ class ModelMultipleChoiceField(ModelChoiceField):
|
|
|
578
578
|
def __init__(self, queryset: Any, **kwargs: Any) -> None:
|
|
579
579
|
super().__init__(queryset, empty_label=None, **kwargs)
|
|
580
580
|
|
|
581
|
-
def to_python(self, value: Any) -> list[Any]: #
|
|
581
|
+
def to_python(self, value: Any) -> list[Any]: # ty: ignore[invalid-method-override]
|
|
582
582
|
if not value:
|
|
583
583
|
return []
|
|
584
584
|
return list(self._check_values(value))
|
|
@@ -74,7 +74,7 @@ class Index:
|
|
|
74
74
|
self.opclasses: tuple[str, ...] = tuple(opclasses)
|
|
75
75
|
self.condition = condition
|
|
76
76
|
self.include = tuple(include) if include else ()
|
|
77
|
-
self.expressions: tuple[Expression, ...] = tuple( #
|
|
77
|
+
self.expressions: tuple[Expression, ...] = tuple( # ty: ignore[invalid-assignment]
|
|
78
78
|
F(expression) if isinstance(expression, str) else expression
|
|
79
79
|
for expression in expressions
|
|
80
80
|
)
|
|
@@ -441,7 +441,7 @@ class IntegerFieldOverflow:
|
|
|
441
441
|
raise self.underflow_exception
|
|
442
442
|
if max_value is not None and rhs > max_value:
|
|
443
443
|
raise self.overflow_exception
|
|
444
|
-
return super().process_rhs(compiler, connection) #
|
|
444
|
+
return super().process_rhs(compiler, connection) # ty: ignore[unresolved-attribute]
|
|
445
445
|
|
|
446
446
|
|
|
447
447
|
class IntegerFieldFloatRounding:
|
|
@@ -455,7 +455,7 @@ class IntegerFieldFloatRounding:
|
|
|
455
455
|
def get_prep_lookup(self) -> Any:
|
|
456
456
|
if isinstance(self.rhs, float):
|
|
457
457
|
self.rhs = math.ceil(self.rhs)
|
|
458
|
-
return super().get_prep_lookup() #
|
|
458
|
+
return super().get_prep_lookup() # ty: ignore[unresolved-attribute]
|
|
459
459
|
|
|
460
460
|
|
|
461
461
|
@IntegerField.register_lookup
|
|
@@ -367,7 +367,7 @@ class Meta:
|
|
|
367
367
|
)
|
|
368
368
|
|
|
369
369
|
try:
|
|
370
|
-
return self.fields_map[field_name] #
|
|
370
|
+
return self.fields_map[field_name] # ty: ignore[invalid-return-type]
|
|
371
371
|
except KeyError:
|
|
372
372
|
raise FieldDoesNotExist(
|
|
373
373
|
f"{self.model} has no reverse relation named '{field_name}'"
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from ..schema import DatabaseSchemaEditor
|
|
2
|
-
from .migration import Migration
|
|
2
|
+
from .migration import Migration
|
|
3
3
|
from .operations import (
|
|
4
4
|
AddField,
|
|
5
5
|
AlterField,
|
|
@@ -19,7 +19,6 @@ from .state import StateModelsRegistry
|
|
|
19
19
|
__all__ = [
|
|
20
20
|
# Migration class
|
|
21
21
|
"Migration",
|
|
22
|
-
"settings_dependency",
|
|
23
22
|
# Model operations
|
|
24
23
|
"CreateModel",
|
|
25
24
|
"DeleteModel",
|
|
@@ -15,7 +15,7 @@ from plain.postgres.fields import (
|
|
|
15
15
|
from plain.postgres.fields.related import ManyToManyField, RelatedField
|
|
16
16
|
from plain.postgres.fields.reverse_related import ManyToManyRel
|
|
17
17
|
from plain.postgres.migrations import operations
|
|
18
|
-
from plain.postgres.migrations.migration import Migration
|
|
18
|
+
from plain.postgres.migrations.migration import Migration
|
|
19
19
|
from plain.postgres.migrations.operations.models import AlterModelOptions
|
|
20
20
|
from plain.postgres.migrations.optimizer import MigrationOptimizer
|
|
21
21
|
from plain.postgres.migrations.questioner import MigrationQuestioner
|
|
@@ -24,7 +24,6 @@ from plain.postgres.migrations.utils import (
|
|
|
24
24
|
RegexObject,
|
|
25
25
|
resolve_relation,
|
|
26
26
|
)
|
|
27
|
-
from plain.runtime import settings
|
|
28
27
|
|
|
29
28
|
if TYPE_CHECKING:
|
|
30
29
|
from plain.postgres.migrations.graph import MigrationGraph
|
|
@@ -230,7 +229,7 @@ class MigrationAutodetector:
|
|
|
230
229
|
field.remote_field, "through", None
|
|
231
230
|
):
|
|
232
231
|
through_key = resolve_relation(
|
|
233
|
-
field.remote_field.through, #
|
|
232
|
+
field.remote_field.through, # ty: ignore[unresolved-attribute]
|
|
234
233
|
package_label,
|
|
235
234
|
model_name,
|
|
236
235
|
)
|
|
@@ -240,23 +239,6 @@ class MigrationAutodetector:
|
|
|
240
239
|
field_name,
|
|
241
240
|
)
|
|
242
241
|
|
|
243
|
-
@staticmethod
|
|
244
|
-
def _resolve_dependency(
|
|
245
|
-
dependency: tuple[str, str, str | None, bool | str],
|
|
246
|
-
) -> tuple[tuple[str, str, str | None, bool | str], bool]:
|
|
247
|
-
"""
|
|
248
|
-
Return the resolved dependency and a boolean denoting whether or not
|
|
249
|
-
it was a settings dependency.
|
|
250
|
-
"""
|
|
251
|
-
if not isinstance(dependency, SettingsTuple):
|
|
252
|
-
return dependency, False
|
|
253
|
-
resolved_package_label, resolved_object_name = getattr(
|
|
254
|
-
settings, dependency[1]
|
|
255
|
-
).split(".")
|
|
256
|
-
return (resolved_package_label, resolved_object_name.lower()) + dependency[
|
|
257
|
-
2:
|
|
258
|
-
], True
|
|
259
|
-
|
|
260
242
|
def _build_migration_list(self, graph: MigrationGraph | None = None) -> None:
|
|
261
243
|
"""
|
|
262
244
|
Chop the lists of operations up into migrations with dependencies on
|
|
@@ -285,12 +267,6 @@ class MigrationAutodetector:
|
|
|
285
267
|
deps_satisfied = True
|
|
286
268
|
operation_dependencies = set()
|
|
287
269
|
for dep in operation._auto_deps:
|
|
288
|
-
# Temporarily resolve the settings dependency to
|
|
289
|
-
# prevent circular references. While keeping the
|
|
290
|
-
# dependency checks on the resolved model, add the
|
|
291
|
-
# settings dependencies.
|
|
292
|
-
original_dep = dep
|
|
293
|
-
dep, is_settings_dep = self._resolve_dependency(dep)
|
|
294
270
|
if dep[0] != package_label:
|
|
295
271
|
# External app dependency. See if it's not yet
|
|
296
272
|
# satisfied.
|
|
@@ -303,11 +279,7 @@ class MigrationAutodetector:
|
|
|
303
279
|
if not deps_satisfied:
|
|
304
280
|
break
|
|
305
281
|
else:
|
|
306
|
-
if
|
|
307
|
-
operation_dependencies.add(
|
|
308
|
-
(original_dep[0], original_dep[1])
|
|
309
|
-
)
|
|
310
|
-
elif dep[0] in self.migrations:
|
|
282
|
+
if dep[0] in self.migrations:
|
|
311
283
|
operation_dependencies.add(
|
|
312
284
|
(dep[0], self.migrations[dep[0]][-1].name)
|
|
313
285
|
)
|
|
@@ -381,9 +353,6 @@ class MigrationAutodetector:
|
|
|
381
353
|
for op in ops:
|
|
382
354
|
ts.add(op)
|
|
383
355
|
for dep in op._auto_deps:
|
|
384
|
-
# Resolve intra-app dependencies to handle circular
|
|
385
|
-
# references involving a settings model.
|
|
386
|
-
dep = self._resolve_dependency(dep)[0]
|
|
387
356
|
if dep[0] != package_label:
|
|
388
357
|
continue
|
|
389
358
|
ts.add(op, *(x for x in ops if self.check_dependency(x, dep)))
|
|
@@ -894,19 +863,19 @@ class MigrationAutodetector:
|
|
|
894
863
|
new_field.remote_field, "model", None
|
|
895
864
|
):
|
|
896
865
|
rename_key = resolve_relation(
|
|
897
|
-
new_field.remote_field.model, #
|
|
866
|
+
new_field.remote_field.model, # ty: ignore[unresolved-attribute]
|
|
898
867
|
package_label,
|
|
899
868
|
model_name,
|
|
900
869
|
)
|
|
901
870
|
if rename_key in self.renamed_models:
|
|
902
|
-
new_field.remote_field.model = old_field.remote_field.model #
|
|
871
|
+
new_field.remote_field.model = old_field.remote_field.model # ty: ignore[unresolved-attribute]
|
|
903
872
|
# Handle ForeignKeyField which can only have a single to_field.
|
|
904
873
|
remote_field_name = getattr(new_field.remote_field, "field_name", None)
|
|
905
874
|
if remote_field_name:
|
|
906
875
|
to_field_rename_key = rename_key + (remote_field_name,)
|
|
907
876
|
if to_field_rename_key in self.renamed_fields:
|
|
908
877
|
# Repoint model name only
|
|
909
|
-
new_field.remote_field.model = old_field.remote_field.model #
|
|
878
|
+
new_field.remote_field.model = old_field.remote_field.model # ty: ignore[unresolved-attribute]
|
|
910
879
|
dependencies.extend(
|
|
911
880
|
self._get_dependencies_for_foreign_key(
|
|
912
881
|
package_label,
|
|
@@ -919,12 +888,12 @@ class MigrationAutodetector:
|
|
|
919
888
|
new_field.remote_field, "through", None
|
|
920
889
|
):
|
|
921
890
|
rename_key = resolve_relation(
|
|
922
|
-
new_field.remote_field.through, #
|
|
891
|
+
new_field.remote_field.through, # ty: ignore[unresolved-attribute]
|
|
923
892
|
package_label,
|
|
924
893
|
model_name,
|
|
925
894
|
)
|
|
926
895
|
if rename_key in self.renamed_models:
|
|
927
|
-
new_field.remote_field.through = old_field.remote_field.through #
|
|
896
|
+
new_field.remote_field.through = old_field.remote_field.through # ty: ignore[unresolved-attribute]
|
|
928
897
|
old_field_dec = self.deep_deconstruct(old_field)
|
|
929
898
|
new_field_dec = self.deep_deconstruct(new_field)
|
|
930
899
|
if old_field_dec != new_field_dec and old_field_name == field_name:
|
|
@@ -357,7 +357,7 @@ class MigrationGraph:
|
|
|
357
357
|
plan = self._generate_plan(nodes, at_end)
|
|
358
358
|
project_state = ProjectState(real_packages=real_packages)
|
|
359
359
|
for node in plan:
|
|
360
|
-
project_state = self.nodes[node].mutate_state(project_state, preserve=False) #
|
|
360
|
+
project_state = self.nodes[node].mutate_state(project_state, preserve=False) # ty: ignore[unresolved-attribute]
|
|
361
361
|
return project_state
|
|
362
362
|
|
|
363
363
|
def __contains__(self, node: tuple[str, str]) -> bool:
|
|
@@ -161,20 +161,3 @@ class Migration:
|
|
|
161
161
|
break
|
|
162
162
|
name = new_name
|
|
163
163
|
return name
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
class SettingsTuple(tuple):
|
|
167
|
-
"""
|
|
168
|
-
Subclass of tuple so Plain can tell this was originally a settings
|
|
169
|
-
dependency when it reads the migration file.
|
|
170
|
-
"""
|
|
171
|
-
|
|
172
|
-
def __new__(cls, value: tuple[str, str], setting: str) -> SettingsTuple:
|
|
173
|
-
self = tuple.__new__(cls, value)
|
|
174
|
-
self.setting = setting
|
|
175
|
-
return self
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
def settings_dependency(value: str) -> SettingsTuple:
|
|
179
|
-
"""Turn a setting value into a dependency."""
|
|
180
|
-
return SettingsTuple((value.split(".", 1)[0], "__first__"), value)
|
|
@@ -33,7 +33,7 @@ class MigrationRecorder:
|
|
|
33
33
|
|
|
34
34
|
_migration_class: type[postgres.Model] | None = None
|
|
35
35
|
|
|
36
|
-
@classproperty #
|
|
36
|
+
@classproperty # ty: ignore[invalid-argument-type]
|
|
37
37
|
def Migration(cls) -> type[postgres.Model]:
|
|
38
38
|
"""
|
|
39
39
|
Lazy load to avoid PackageRegistryNotReady if installed packages import
|
|
@@ -19,7 +19,6 @@ from plain.postgres.enums import Choices
|
|
|
19
19
|
from plain.postgres.fields import Field
|
|
20
20
|
from plain.postgres.migrations.operations.base import Operation
|
|
21
21
|
from plain.postgres.migrations.utils import COMPILED_REGEX_TYPE, RegexObject
|
|
22
|
-
from plain.runtime import SettingsReference
|
|
23
22
|
from plain.utils.functional import LazyObject, Promise
|
|
24
23
|
|
|
25
24
|
|
|
@@ -277,13 +276,6 @@ class SetSerializer(BaseSequenceSerializer):
|
|
|
277
276
|
return "{%s}" if self.value else "set(%s)"
|
|
278
277
|
|
|
279
278
|
|
|
280
|
-
class SettingsReferenceSerializer(BaseSerializer):
|
|
281
|
-
def serialize(self) -> tuple[str, set[str]]:
|
|
282
|
-
return f"settings.{self.value.setting_name}", {
|
|
283
|
-
"from plain.runtime import settings"
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
|
|
287
279
|
class TupleSerializer(BaseSequenceSerializer):
|
|
288
280
|
def _format(self) -> str:
|
|
289
281
|
# When len(value)==0, the empty tuple should be serialized as "()",
|
|
@@ -326,7 +318,6 @@ class Serializer:
|
|
|
326
318
|
enum.Enum: EnumSerializer,
|
|
327
319
|
datetime.datetime: DatetimeDatetimeSerializer,
|
|
328
320
|
(datetime.date, datetime.timedelta, datetime.time): DateTimeSerializer,
|
|
329
|
-
SettingsReference: SettingsReferenceSerializer,
|
|
330
321
|
float: FloatSerializer,
|
|
331
322
|
(bool, int, types.NoneType, bytes, str, range): BaseSimpleSerializer,
|
|
332
323
|
decimal.Decimal: DecimalSerializer,
|
|
@@ -349,7 +340,7 @@ class Serializer:
|
|
|
349
340
|
raise ValueError(
|
|
350
341
|
f"'{serializer.__name__}' must inherit from 'BaseSerializer'."
|
|
351
342
|
)
|
|
352
|
-
cls._registry[type_] = serializer #
|
|
343
|
+
cls._registry[type_] = serializer # ty: ignore[invalid-assignment]
|
|
353
344
|
|
|
354
345
|
|
|
355
346
|
def serializer_factory(value: Any) -> BaseSerializer:
|
|
@@ -170,12 +170,12 @@ class ProjectState:
|
|
|
170
170
|
if reference.to:
|
|
171
171
|
changed_field = field.clone()
|
|
172
172
|
assert changed_field.remote_field is not None
|
|
173
|
-
changed_field.remote_field.model = new_remote_model #
|
|
173
|
+
changed_field.remote_field.model = new_remote_model # ty: ignore[invalid-assignment]
|
|
174
174
|
if reference.through:
|
|
175
175
|
if changed_field is None:
|
|
176
176
|
changed_field = field.clone()
|
|
177
177
|
assert changed_field.remote_field is not None
|
|
178
|
-
changed_field.remote_field.through = new_remote_model #
|
|
178
|
+
changed_field.remote_field.through = new_remote_model # ty: ignore[unresolved-attribute]
|
|
179
179
|
if changed_field:
|
|
180
180
|
model_state.fields[name] = changed_field
|
|
181
181
|
to_reload.add((model_state.package_label, model_state.name_lower))
|