plain 0.68.0__py3-none-any.whl → 0.69.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.
plain/CHANGELOG.md CHANGED
@@ -1,5 +1,27 @@
1
1
  # plain changelog
2
2
 
3
+ ## [0.69.0](https://github.com/dropseed/plain/releases/plain@0.69.0) (2025-09-29)
4
+
5
+ ### What's changed
6
+
7
+ - Model-related exceptions (`FieldDoesNotExist`, `FieldError`, `ObjectDoesNotExist`, `MultipleObjectsReturned`, `EmptyResultSet`, `FullResultSet`) moved from `plain.exceptions` to `plain.models.exceptions` ([1c02564](https://github.com/dropseed/plain/commit/1c02564561))
8
+ - Added `plain dev` alias prompt that suggests adding `p` as a shell alias for convenience ([d913b44](https://github.com/dropseed/plain/commit/d913b44fab))
9
+
10
+ ### Upgrade instructions
11
+
12
+ - Replace imports of `FieldDoesNotExist`, `FieldError`, `ObjectDoesNotExist`, `MultipleObjectsReturned`, `EmptyResultSet`, or `FullResultSet` from `plain.exceptions` to `plain.models.exceptions`
13
+ - If you're using `ObjectDoesNotExist` in views, update your import from `plain.exceptions.ObjectDoesNotExist` to `plain.models.exceptions.ObjectDoesNotExist`
14
+
15
+ ## [0.68.1](https://github.com/dropseed/plain/releases/plain@0.68.1) (2025-09-25)
16
+
17
+ ### What's changed
18
+
19
+ - Preflight checks are now sorted by name for consistent ordering ([cb8e160](https://github.com/dropseed/plain/commit/cb8e160934))
20
+
21
+ ### Upgrade instructions
22
+
23
+ - No changes required
24
+
3
25
  ## [0.68.0](https://github.com/dropseed/plain/releases/plain@0.68.0) (2025-09-25)
4
26
 
5
27
  ### What's changed
@@ -11,7 +33,7 @@
11
33
 
12
34
  ### Upgrade instructions
13
35
 
14
- - Use `plain preflight check` instead of `plain preflight` to run all checks
36
+ - Update any uses of the `plain preflight` command to `plain preflight check`, and remove the `--database` and `--fail-level` options which no longer exist
15
37
  - Custom preflight checks should be class based, extending `PreflightCheck` and implementing the `run()` method
16
38
  - Preflight checks need to be registered with a custom name (ex. `@register_check("app.my_custom_check")`) and optionally with `deploy=True` if it should run in only in deploy mode
17
39
  - Preflight results should use `PreflightResult` (optionally with `warning=True`) instead of `preflight.Warning` or `preflight.Error`
plain/exceptions.py CHANGED
@@ -6,7 +6,7 @@ import operator
6
6
 
7
7
  from plain.utils.hashable import make_hashable
8
8
 
9
- # MARK: Configuration and Registry
9
+ # MARK: Configuration and Package Registry
10
10
 
11
11
 
12
12
  class PackageRegistryNotReady(Exception):
@@ -21,33 +21,6 @@ class ImproperlyConfigured(Exception):
21
21
  pass
22
22
 
23
23
 
24
- # MARK: Model and Field Errors
25
-
26
-
27
- class FieldDoesNotExist(Exception):
28
- """The requested model field does not exist"""
29
-
30
- pass
31
-
32
-
33
- class FieldError(Exception):
34
- """Some kind of problem with a model field."""
35
-
36
- pass
37
-
38
-
39
- class ObjectDoesNotExist(Exception):
40
- """The requested object does not exist"""
41
-
42
- pass
43
-
44
-
45
- class MultipleObjectsReturned(Exception):
46
- """The query returned multiple objects when only one was expected."""
47
-
48
- pass
49
-
50
-
51
24
  # MARK: Security and Suspicious Operations
52
25
 
53
26
 
@@ -210,18 +183,3 @@ class ValidationError(Exception):
210
183
  if hasattr(self, "error_dict"):
211
184
  return hash(make_hashable(self.error_dict))
212
185
  return hash(tuple(sorted(self.error_list, key=operator.attrgetter("message"))))
213
-
214
-
215
- # MARK: Database
216
-
217
-
218
- class EmptyResultSet(Exception):
219
- """A database query predicate is impossible."""
220
-
221
- pass
222
-
223
-
224
- class FullResultSet(Exception):
225
- """A database query predicate is matches everything."""
226
-
227
- pass
@@ -28,7 +28,7 @@ class CheckRegistry:
28
28
  "Check for typos or remove outdated check names."
29
29
  )
30
30
 
31
- for name, (check_class, deploy) in self.checks.items():
31
+ for name, (check_class, deploy) in sorted(self.checks.items()):
32
32
  # Skip silenced checks
33
33
  if name in silenced_checks:
34
34
  continue
plain/views/objects.py CHANGED
@@ -1,7 +1,13 @@
1
1
  from functools import cached_property
2
2
  from typing import Any
3
3
 
4
- from plain.exceptions import ImproperlyConfigured, ObjectDoesNotExist
4
+ from plain.exceptions import ImproperlyConfigured
5
+
6
+ try:
7
+ from plain.models.exceptions import ObjectDoesNotExist
8
+ except ImportError:
9
+ ObjectDoesNotExist = None
10
+
5
11
  from plain.forms import Form
6
12
  from plain.http import Http404
7
13
 
@@ -42,8 +48,12 @@ class ObjectTemplateViewMixin:
42
48
  def object(self) -> Any:
43
49
  try:
44
50
  obj = self.get_object()
45
- except ObjectDoesNotExist:
46
- raise Http404
51
+ except Exception as e:
52
+ # If ObjectDoesNotExist is available and this is that exception, raise 404
53
+ if ObjectDoesNotExist and isinstance(e, ObjectDoesNotExist):
54
+ raise Http404
55
+ # Otherwise, let other exceptions bubble up
56
+ raise
47
57
 
48
58
  # Also raise 404 if get_object() returns None
49
59
  if not obj:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: plain
3
- Version: 0.68.0
3
+ Version: 0.69.0
4
4
  Summary: A web framework for building products with Python.
5
5
  Author-email: Dave Gaeddert <dave.gaeddert@dropseed.dev>
6
6
  License-File: LICENSE
@@ -1,9 +1,9 @@
1
1
  plain/AGENTS.md,sha256=5XMGBpJgbCNIpp60DPXB7bpAtFk8FAzqiZke95T965o,1038
2
- plain/CHANGELOG.md,sha256=w-r_nifYj7nhHF3pbn3fJC0r3j9PhqYVBoTKeFTnDiU,18152
2
+ plain/CHANGELOG.md,sha256=gcIkgAGt6KaNQ998wBmK_syzwnL8mM44zvLaNYL1g_o,19427
3
3
  plain/README.md,sha256=5BJyKhf0TDanWVbOQyZ3zsi5Lov9xk-LlJYCDWofM6Y,4078
4
4
  plain/__main__.py,sha256=GK39854Lc_LO_JP8DzY9Y2MIQ4cQEl7SXFJy244-lC8,110
5
5
  plain/debug.py,sha256=XdjnXcbPGsi0J2SpHGaLthhYU5AjhBlkHdemaP4sbYY,758
6
- plain/exceptions.py,sha256=QepC5UG5IBGW3h2cimOqGtjslAzvYdLYIn6xHdyco-Y,5868
6
+ plain/exceptions.py,sha256=4t4GEPinAIfecFlUEUQLOh0YFe316AkvXkFON3y53gs,5209
7
7
  plain/json.py,sha256=McJdsbMT1sYwkGRG--f2NSZz0hVXPMix9x3nKaaak2o,1262
8
8
  plain/paginator.py,sha256=iXiOyt2r_YwNrkqCRlaU7V-M_BKaaQ8XZElUBVa6yeU,5844
9
9
  plain/signing.py,sha256=i8Bf12c96u_1BZYjETiixhsLAWMAt_y4CIYZOsI6IVA,8295
@@ -93,7 +93,7 @@ plain/preflight/README.md,sha256=vR43F_ls81hRSo7J2NNZ4VOMoRaJ1bS5JwA6l4ez36g,178
93
93
  plain/preflight/__init__.py,sha256=-uBIVLD1DlJUVypQsEcrOtaNAhECbOpKhyoz0c_WMhA,416
94
94
  plain/preflight/checks.py,sha256=hEJbP5KHQmdmfcr7cHt45tmdwmjomd8nvnCmQYxxCTo,245
95
95
  plain/preflight/files.py,sha256=k1Gsy8QJGbatMe_1ylSaDs7azDnh6qv4CftFpOnbDr8,779
96
- plain/preflight/registry.py,sha256=65yiz9Wm8dOTMs9h15txNu7SRace6mbLI-sfn6GxMBQ,2427
96
+ plain/preflight/registry.py,sha256=rLGTaxAG_87lbcnwfESpSNmC9IS9yHsKkV7-mRizZ5s,2435
97
97
  plain/preflight/results.py,sha256=wgZgISGt9KGZzgmM_HdFUl6ZmRHQlKhvQClP7KbGgcc,949
98
98
  plain/preflight/security.py,sha256=eqvJTe691WihtLN8hi2tj5wxH8ZgcsY5QFbYkorkNS0,2910
99
99
  plain/preflight/urls.py,sha256=QVBcZCv891ZeLNVXTZS0w6bb54w5UOpZXP21Li7gt3o,339
@@ -159,11 +159,11 @@ plain/views/base.py,sha256=CC9UvMZeAjVvi90vGjoZzsQ0jnhbg3-7qCKQ8-Pb6cg,4184
159
159
  plain/views/errors.py,sha256=jbNCJIzowwCsEvqyJ3opMeZpPDqTyhtrbqb0VnAm2HE,1263
160
160
  plain/views/exceptions.py,sha256=b4euI49ZUKS9O8AGAcFfiDpstzkRAuuj_uYQXzWNHME,138
161
161
  plain/views/forms.py,sha256=ESZOXuo6IeYixp1RZvPb94KplkowRiwO2eGJCM6zJI0,2400
162
- plain/views/objects.py,sha256=v3Vgvdoc1s0QW6JNWWrO5XXy9zF7vgwndgxX1eOSQoE,4999
162
+ plain/views/objects.py,sha256=ejtO9108BJN1c6FccwySyxuONtT0V3dNslirg1jq8rw,5329
163
163
  plain/views/redirect.py,sha256=Xpb3cB7nZYvKgkNqcAxf9Jwm2SWcQ0u2xz4oO5M3vP8,1909
164
164
  plain/views/templates.py,sha256=oAlebEyfES0rzBhfyEJzFmgLkpkbleA6Eip-8zDp-yk,1863
165
- plain-0.68.0.dist-info/METADATA,sha256=mE7UvxxqukxfFjudAuB0gaGa7gagrESPTRmByQOVb9M,4488
166
- plain-0.68.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
167
- plain-0.68.0.dist-info/entry_points.txt,sha256=wvMzY-iREvfqRgyLm77htPp4j_8CQslLoZA15_AnNo8,171
168
- plain-0.68.0.dist-info/licenses/LICENSE,sha256=m0D5O7QoH9l5Vz_rrX_9r-C8d9UNr_ciK6Qwac7o6yo,3175
169
- plain-0.68.0.dist-info/RECORD,,
165
+ plain-0.69.0.dist-info/METADATA,sha256=fuGXnj06asHYOdbiynlzX91JuwUwu71fsOarnwHJlbQ,4488
166
+ plain-0.69.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
167
+ plain-0.69.0.dist-info/entry_points.txt,sha256=wvMzY-iREvfqRgyLm77htPp4j_8CQslLoZA15_AnNo8,171
168
+ plain-0.69.0.dist-info/licenses/LICENSE,sha256=m0D5O7QoH9l5Vz_rrX_9r-C8d9UNr_ciK6Qwac7o6yo,3175
169
+ plain-0.69.0.dist-info/RECORD,,
File without changes