plain.postgres 0.110.0__tar.gz → 0.110.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.
Files changed (222) hide show
  1. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/PKG-INFO +1 -1
  2. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/CHANGELOG.md +20 -0
  3. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/agents/.claude/rules/plain-postgres.md +1 -10
  4. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/enums.py +1 -1
  5. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/expressions.py +13 -9
  6. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/sql/compiler.py +8 -3
  7. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/test/pytest.py +3 -3
  8. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/pyproject.toml +1 -1
  9. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/public/test_exceptions.py +2 -2
  10. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/public/test_related.py +1 -1
  11. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/.gitignore +0 -0
  12. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/CLAUDE.md +0 -0
  13. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/LICENSE +0 -0
  14. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/README.md +0 -0
  15. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/README.md +0 -0
  16. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/__init__.py +0 -0
  17. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/adapters.py +0 -0
  18. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/agents/.claude/skills/plain-postgres-doctor/SKILL.md +0 -0
  19. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/aggregates.py +0 -0
  20. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/base.py +0 -0
  21. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/cli/__init__.py +0 -0
  22. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/cli/converge.py +0 -0
  23. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/cli/core.py +0 -0
  24. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/cli/decorators.py +0 -0
  25. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/cli/diagnose.py +0 -0
  26. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/cli/migrations.py +0 -0
  27. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/cli/schema.py +0 -0
  28. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/cli/sync.py +0 -0
  29. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/config.py +0 -0
  30. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/connection.py +0 -0
  31. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/constants.py +0 -0
  32. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/constraints.py +0 -0
  33. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/convergence/__init__.py +0 -0
  34. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/convergence/analysis.py +0 -0
  35. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/convergence/fixes.py +0 -0
  36. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/convergence/planning.py +0 -0
  37. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/database_url.py +0 -0
  38. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/db.py +0 -0
  39. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/ddl.py +0 -0
  40. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/default_settings.py +0 -0
  41. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/deletion.py +0 -0
  42. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/dialect.py +0 -0
  43. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/entrypoints.py +0 -0
  44. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/exceptions.py +0 -0
  45. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/fields/__init__.py +0 -0
  46. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/fields/base.py +0 -0
  47. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/fields/binary.py +0 -0
  48. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/fields/boolean.py +0 -0
  49. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/fields/duration.py +0 -0
  50. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/fields/encrypted.py +0 -0
  51. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/fields/json.py +0 -0
  52. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/fields/mixins.py +0 -0
  53. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/fields/network.py +0 -0
  54. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/fields/numeric.py +0 -0
  55. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/fields/primary_key.py +0 -0
  56. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/fields/related.py +0 -0
  57. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/fields/related_descriptors.py +0 -0
  58. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/fields/related_lookups.py +0 -0
  59. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/fields/related_managers.py +0 -0
  60. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/fields/reverse_descriptors.py +0 -0
  61. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/fields/reverse_related.py +0 -0
  62. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/fields/temporal.py +0 -0
  63. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/fields/text.py +0 -0
  64. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/fields/timezones.py +0 -0
  65. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/fields/uuid.py +0 -0
  66. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/forms.py +0 -0
  67. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/functions/__init__.py +0 -0
  68. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/functions/comparison.py +0 -0
  69. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/functions/datetime.py +0 -0
  70. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/functions/math.py +0 -0
  71. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/functions/mixins.py +0 -0
  72. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/functions/random.py +0 -0
  73. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/functions/text.py +0 -0
  74. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/functions/uuid.py +0 -0
  75. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/functions/window.py +0 -0
  76. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/indexes.py +0 -0
  77. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/introspection/__init__.py +0 -0
  78. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/introspection/health/__init__.py +0 -0
  79. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/introspection/health/checks_cumulative.py +0 -0
  80. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/introspection/health/checks_snapshot.py +0 -0
  81. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/introspection/health/checks_structural.py +0 -0
  82. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/introspection/health/context.py +0 -0
  83. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/introspection/health/helpers.py +0 -0
  84. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/introspection/health/ownership.py +0 -0
  85. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/introspection/health/runner.py +0 -0
  86. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/introspection/health/types.py +0 -0
  87. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/introspection/schema.py +0 -0
  88. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/lookups.py +0 -0
  89. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/meta.py +0 -0
  90. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/middleware.py +0 -0
  91. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/migrations/__init__.py +0 -0
  92. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/migrations/autodetector.py +0 -0
  93. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/migrations/exceptions.py +0 -0
  94. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/migrations/executor.py +0 -0
  95. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/migrations/graph.py +0 -0
  96. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/migrations/loader.py +0 -0
  97. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/migrations/migration.py +0 -0
  98. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/migrations/operations/__init__.py +0 -0
  99. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/migrations/operations/base.py +0 -0
  100. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/migrations/operations/fields.py +0 -0
  101. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/migrations/operations/models.py +0 -0
  102. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/migrations/operations/special.py +0 -0
  103. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/migrations/optimizer.py +0 -0
  104. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/migrations/questioner.py +0 -0
  105. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/migrations/recorder.py +0 -0
  106. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/migrations/serializer.py +0 -0
  107. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/migrations/state.py +0 -0
  108. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/migrations/utils.py +0 -0
  109. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/migrations/writer.py +0 -0
  110. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/options.py +0 -0
  111. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/otel.py +0 -0
  112. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/preflight/__init__.py +0 -0
  113. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/preflight/database.py +0 -0
  114. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/preflight/indexes.py +0 -0
  115. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/preflight/models.py +0 -0
  116. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/query.py +0 -0
  117. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/query_utils.py +0 -0
  118. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/registry.py +0 -0
  119. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/schema.py +0 -0
  120. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/sources.py +0 -0
  121. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/sql/__init__.py +0 -0
  122. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/sql/constants.py +0 -0
  123. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/sql/datastructures.py +0 -0
  124. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/sql/query.py +0 -0
  125. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/sql/where.py +0 -0
  126. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/test/__init__.py +0 -0
  127. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/test/database.py +0 -0
  128. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/transaction.py +0 -0
  129. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/types.py +0 -0
  130. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/types.pyi +0 -0
  131. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/plain/postgres/utils.py +0 -0
  132. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/app/examples/forms.py +0 -0
  133. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/app/examples/migrations/0001_initial.py +0 -0
  134. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/app/examples/migrations/0002_test_field_removed.py +0 -0
  135. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/app/examples/migrations/0003_deleteparent_childsetnull_childsetdefault_and_more.py +0 -0
  136. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/app/examples/migrations/0004_defaultquerysetmodel_mixintestmodel_and_more.py +0 -0
  137. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/app/examples/migrations/0005_feature_carfeature_car_features.py +0 -0
  138. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/app/examples/migrations/0006_secretstore.py +0 -0
  139. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/app/examples/migrations/0007_treenode_unconstrainedchild.py +0 -0
  140. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/app/examples/migrations/0008_setsentinelparent_diamondparenta_midparent_and_more.py +0 -0
  141. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/app/examples/migrations/0009_circb_circa_circb_partner.py +0 -0
  142. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/app/examples/migrations/0010_hideableitem.py +0 -0
  143. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/app/examples/migrations/0011_defaultsexample.py +0 -0
  144. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/app/examples/migrations/0012_iterationexample.py +0 -0
  145. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/app/examples/migrations/0013_indexexample_constraintexample_nullabilityexample.py +0 -0
  146. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/app/examples/migrations/0014_widget_rename_feature_tag_remove_carfeature_car_and_more.py +0 -0
  147. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/app/examples/migrations/0015_dbdefaultsexample.py +0 -0
  148. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/app/examples/migrations/0016_formsexample.py +0 -0
  149. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/app/examples/migrations/0017_random_string_token.py +0 -0
  150. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/app/examples/migrations/0018_storageparametersexample.py +0 -0
  151. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/app/examples/migrations/__init__.py +0 -0
  152. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/app/examples/models/__init__.py +0 -0
  153. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/app/examples/models/constraints.py +0 -0
  154. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/app/examples/models/defaults.py +0 -0
  155. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/app/examples/models/delete.py +0 -0
  156. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/app/examples/models/encrypted.py +0 -0
  157. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/app/examples/models/forms.py +0 -0
  158. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/app/examples/models/indexes.py +0 -0
  159. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/app/examples/models/iteration.py +0 -0
  160. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/app/examples/models/mixins.py +0 -0
  161. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/app/examples/models/nullability.py +0 -0
  162. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/app/examples/models/querysets.py +0 -0
  163. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/app/examples/models/relationships.py +0 -0
  164. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/app/examples/models/storage_parameters.py +0 -0
  165. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/app/examples/models/trees.py +0 -0
  166. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/app/examples/models/unregistered.py +0 -0
  167. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/app/examples/urls.py +0 -0
  168. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/app/examples/views.py +0 -0
  169. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/app/settings.py +0 -0
  170. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/app/urls.py +0 -0
  171. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/conftest.py +0 -0
  172. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/conftest_convergence.py +0 -0
  173. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/internal/test_autodetector_not_null_errors.py +0 -0
  174. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/internal/test_autodetector_type_change.py +0 -0
  175. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/internal/test_connection_isolation.py +0 -0
  176. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/internal/test_connection_lifecycle.py +0 -0
  177. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/internal/test_connection_pool.py +0 -0
  178. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/internal/test_connection_self_heal.py +0 -0
  179. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/internal/test_constraint_violation_error.py +0 -0
  180. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/internal/test_convergence.py +0 -0
  181. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/internal/test_convergence_constraints.py +0 -0
  182. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/internal/test_convergence_defaults.py +0 -0
  183. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/internal/test_convergence_fk.py +0 -0
  184. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/internal/test_convergence_indexes.py +0 -0
  185. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/internal/test_convergence_nullability.py +0 -0
  186. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/internal/test_convergence_storage_parameters.py +0 -0
  187. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/internal/test_convergence_timeouts.py +0 -0
  188. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/internal/test_db_expression_defaults.py +0 -0
  189. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/internal/test_diagnose.py +0 -0
  190. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/internal/test_executor_connection_hook.py +0 -0
  191. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/internal/test_fk_characterization.py +0 -0
  192. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/internal/test_health.py +0 -0
  193. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/internal/test_introspection.py +0 -0
  194. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/internal/test_literal_default_persistence.py +0 -0
  195. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/internal/test_management_connection.py +0 -0
  196. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/internal/test_migration_executor.py +0 -0
  197. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/internal/test_no_callable_defaults.py +0 -0
  198. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/internal/test_otel_metrics.py +0 -0
  199. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/internal/test_preflight_duplicate_indexes.py +0 -0
  200. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/internal/test_preflight_fk_composite_hint.py +0 -0
  201. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/internal/test_preflight_fk_coverage.py +0 -0
  202. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/internal/test_schema_normalize_type.py +0 -0
  203. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/internal/test_schema_timeouts.py +0 -0
  204. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/public/test_create_update.py +0 -0
  205. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/public/test_database_url.py +0 -0
  206. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/public/test_deferred_loading.py +0 -0
  207. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/public/test_delete_behaviors.py +0 -0
  208. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/public/test_encrypted_fields.py +0 -0
  209. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/public/test_field_defaults.py +0 -0
  210. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/public/test_functions_uuid.py +0 -0
  211. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/public/test_integrity_error_mapping.py +0 -0
  212. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/public/test_iterator.py +0 -0
  213. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/public/test_m2m.py +0 -0
  214. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/public/test_manager_assignment.py +0 -0
  215. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/public/test_manual_pk.py +0 -0
  216. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/public/test_mixins.py +0 -0
  217. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/public/test_modelform_roundtrip.py +0 -0
  218. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/public/test_queryset_repr.py +0 -0
  219. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/public/test_random_string_field.py +0 -0
  220. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/public/test_raw_query.py +0 -0
  221. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/public/test_read_only_transactions.py +0 -0
  222. {plain_postgres-0.110.0 → plain_postgres-0.110.2}/tests/public/test_related_instance_filter.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: plain.postgres
3
- Version: 0.110.0
3
+ Version: 0.110.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
@@ -1,5 +1,25 @@
1
1
  # plain-postgres changelog
2
2
 
3
+ ## [0.110.2](https://github.com/dropseed/plain/releases/plain-postgres@0.110.2) (2026-06-26)
4
+
5
+ ### What's changed
6
+
7
+ - Internal type-annotation cleanups (`Func` expression attributes, enum choices) and a dev-dependency bump (pytest 9.1.1) to clear a security advisory. No public API changes. ([288bbf0bb1](https://github.com/dropseed/plain/commit/288bbf0bb1))
8
+
9
+ ### Upgrade instructions
10
+
11
+ - No changes required.
12
+
13
+ ## [0.110.1](https://github.com/dropseed/plain/releases/plain-postgres@0.110.1) (2026-06-22)
14
+
15
+ ### What's changed
16
+
17
+ - Internal: the ordering infinite-loop guard builds its join signature with `isinstance(alias, Join)` instead of `getattr(alias, "join_col", None)`, keeping `.join_col` greppable and type-checked. No behavior change. ([c813405f](https://github.com/dropseed/plain/commit/c813405f))
18
+
19
+ ### Upgrade instructions
20
+
21
+ - No changes required.
22
+
3
23
  ## [0.110.0](https://github.com/dropseed/plain/releases/plain-postgres@0.110.0) (2026-06-17)
4
24
 
5
25
  ### What's changed
@@ -39,16 +39,7 @@ Do NOT import field classes directly from `plain.postgres` or `plain.postgres.fi
39
39
 
40
40
  ## Schema Changes
41
41
 
42
- When creating new models or modifying existing model fields/relationships, always enter plan mode first. Database schema is hard to change after the fact, so get the design right before writing code.
43
-
44
- In your plan, present:
45
-
46
- - Proposed schema as a table (model, field, type, constraints)
47
- - Relationship cardinality (1:1, 1:N, M:N)
48
- - Key decisions: nullable vs default, indexing, cascade behavior
49
- - Whether the data could live on an existing model instead of a new one
50
-
51
- Get approval before writing any model code or generating migrations.
42
+ Migrations are annoying to revise after the fact; convergence is cheap. So before making a batch of migration-generating changes — new models, new columns, or column-type changes think the design through first. Nullability, defaults, indexes, constraints, `on_delete`, and `choices` aren't migrations; they're convergence (edit the model and re-sync), so they stay cheap to revise. For a large set of migration-dependent changes, surfacing the design first (plan mode fits) is worth it.
52
43
 
53
44
  ## Migrations vs Convergence
54
45
 
@@ -58,7 +58,7 @@ class ChoicesMeta(enum.EnumMeta):
58
58
  @property
59
59
  def choices(cls) -> list[tuple[Any, str]]:
60
60
  empty = [(None, cls.__empty__)] if hasattr(cls, "__empty__") else []
61
- return empty + [(member.value, member.label) for member in cls] # ty: ignore[unresolved-attribute, invalid-return-type]
61
+ return empty + [(member.value, member.label) for member in cls] # ty: ignore[unresolved-attribute]
62
62
 
63
63
  @property
64
64
  def labels(cls) -> list[str]:
@@ -8,7 +8,7 @@ from collections import defaultdict
8
8
  from decimal import Decimal
9
9
  from functools import cached_property
10
10
  from types import NoneType
11
- from typing import TYPE_CHECKING, Any, Protocol, Self, runtime_checkable
11
+ from typing import TYPE_CHECKING, Any, Protocol, Self, cast, runtime_checkable
12
12
  from uuid import UUID
13
13
 
14
14
  import psycopg
@@ -911,10 +911,10 @@ class OuterRef(F):
911
911
  class Func(Expression):
912
912
  """An SQL function call."""
913
913
 
914
- function = None
915
- template = "%(function)s(%(expressions)s)"
916
- arg_joiner = ", "
917
- arity = None # The number of arguments the function accepts.
914
+ function: str | None = None
915
+ template: str = "%(function)s(%(expressions)s)"
916
+ arg_joiner: str = ", "
917
+ arity: int | None = None # The number of arguments the function accepts.
918
918
 
919
919
  def __init__(
920
920
  self, *expressions: Any, output_field: Field | None = None, **extra: Any
@@ -1001,10 +1001,14 @@ class Func(Expression):
1001
1001
  data["function"] = function
1002
1002
  else:
1003
1003
  data.setdefault("function", self.function)
1004
- template = template or data.get("template", self.template)
1005
- arg_joiner = arg_joiner or data.get("arg_joiner", self.arg_joiner)
1006
- data["expressions"] = data["field"] = arg_joiner.join(sql_parts)
1007
- return template % data, params
1004
+ # `data` is typed dict[str, Any], so the override values come back as
1005
+ # Any; they are always strings, so cast to keep the `or` fallback typed.
1006
+ resolved_template = template or cast(str, data.get("template", self.template))
1007
+ resolved_joiner = arg_joiner or cast(
1008
+ str, data.get("arg_joiner", self.arg_joiner)
1009
+ )
1010
+ data["expressions"] = data["field"] = resolved_joiner.join(sql_parts)
1011
+ return resolved_template % data, params
1008
1012
 
1009
1013
  def copy(self) -> Self:
1010
1014
  clone = super().copy()
@@ -42,6 +42,7 @@ from plain.postgres.sql.constants import (
42
42
  ORDER_DIR,
43
43
  SINGLE,
44
44
  )
45
+ from plain.postgres.sql.datastructures import Join
45
46
  from plain.postgres.sql.query import Query, get_order_dir
46
47
  from plain.postgres.transaction import TransactionManagementError
47
48
  from plain.utils.hashable import make_hashable
@@ -343,7 +344,7 @@ class SQLCompiler:
343
344
  if self.query.select_related:
344
345
  related_klass_infos = self.get_related_selections(select, select_mask)
345
346
  if klass_info is not None:
346
- klass_info["related_klass_infos"] = related_klass_infos # ty: ignore[invalid-assignment] (heterogeneous klass_info dict)
347
+ klass_info["related_klass_infos"] = related_klass_infos
347
348
 
348
349
  ret = []
349
350
  col_idx = 1
@@ -903,10 +904,14 @@ class SQLCompiler:
903
904
  and field.name != pieces[-1]
904
905
  and not getattr(transform_function, "has_transforms", False)
905
906
  ):
906
- # Firstly, avoid infinite loops.
907
+ # Firstly, avoid infinite loops. Each join contributes its column
908
+ # pair to the signature; the base table (no join_col) contributes
909
+ # None. isinstance keeps `.join_col` greppable and type-checked.
907
910
  already_seen = already_seen or set()
911
+ alias_map = self.query.alias_map
908
912
  join_tuple = tuple(
909
- getattr(self.query.alias_map[j], "join_col", None) for j in joins
913
+ alias_map[j].join_col if isinstance(alias_map[j], Join) else None
914
+ for j in joins
910
915
  )
911
916
  if join_tuple in already_seen:
912
917
  raise FieldError("Infinite loop caused by ordering.")
@@ -24,7 +24,7 @@ def _db_disabled() -> Generator[None]:
24
24
  """
25
25
 
26
26
  def cursor_disabled(self: Any) -> None:
27
- pytest.fail("Database access not allowed without the `db` fixture") # ty: ignore[invalid-argument-type]
27
+ pytest.fail("Database access not allowed without the `db` fixture")
28
28
 
29
29
  # Save original cursor method and replace with disabled version
30
30
  setattr(DatabaseConnection, "_enabled_cursor", DatabaseConnection.cursor)
@@ -63,7 +63,7 @@ def setup_db(request: Any) -> Generator[None]:
63
63
  @pytest.fixture
64
64
  def db(setup_db: Any, request: Any) -> Generator[None]:
65
65
  if "isolated_db" in request.fixturenames:
66
- pytest.fail("The 'db' and 'isolated_db' fixtures cannot be used together") # ty: ignore[invalid-argument-type]
66
+ pytest.fail("The 'db' and 'isolated_db' fixtures cannot be used together")
67
67
 
68
68
  # Set .cursor() back to the original implementation to unblock it
69
69
  DatabaseConnection.cursor = getattr(DatabaseConnection, "_enabled_cursor")
@@ -101,7 +101,7 @@ def isolated_db(request: Any) -> Generator[None]:
101
101
  test database.
102
102
  """
103
103
  if "db" in request.fixturenames:
104
- pytest.fail("The 'db' and 'isolated_db' fixtures cannot be used together") # ty: ignore[invalid-argument-type]
104
+ pytest.fail("The 'db' and 'isolated_db' fixtures cannot be used together")
105
105
  # Set .cursor() back to the original implementation to unblock it
106
106
  DatabaseConnection.cursor = getattr(DatabaseConnection, "_enabled_cursor")
107
107
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "plain.postgres"
3
- version = "0.110.0"
3
+ version = "0.110.2"
4
4
  description = "Model your data and store it in a database."
5
5
  authors = [{ name = "Dave Gaeddert", email = "dave.gaeddert@dropseed.dev" }]
6
6
  readme = "README.md"
@@ -62,11 +62,11 @@ def test_base_exceptions_from_plain_exceptions():
62
62
  except ObjectDoesNotExist:
63
63
  pass # Should work due to inheritance
64
64
  except Exception:
65
- pytest.fail("Should have caught with base ObjectDoesNotExist") # ty: ignore[invalid-argument-type]
65
+ pytest.fail("Should have caught with base ObjectDoesNotExist")
66
66
 
67
67
  try:
68
68
  raise IterationExample.MultipleObjectsReturned("model-specific exception")
69
69
  except MultipleObjectsReturned:
70
70
  pass # Should work due to inheritance
71
71
  except Exception:
72
- pytest.fail("Should have caught with base MultipleObjectsReturned") # ty: ignore[invalid-argument-type]
72
+ pytest.fail("Should have caught with base MultipleObjectsReturned")
@@ -55,7 +55,7 @@ class TestForwardForeignKeyDescriptor:
55
55
  except Exception as e:
56
56
  # For now, accept that nullable FK behavior might need adjustment
57
57
  # The core relationship functionality works
58
- pytest.skip(f"Nullable FK handling needs refinement: {e}") # ty: ignore[too-many-positional-arguments]
58
+ pytest.skip(f"Nullable FK handling needs refinement: {e}")
59
59
 
60
60
 
61
61
  class TestReverseForeignKey: