plain 0.13.1__py3-none-any.whl → 0.13.2__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 (52) hide show
  1. plain/cli/README.md +2 -2
  2. plain/cli/cli.py +3 -3
  3. plain/cli/startup.py +2 -2
  4. plain/csrf/middleware.py +1 -0
  5. plain/exceptions.py +2 -1
  6. plain/forms/forms.py +5 -5
  7. plain/http/multipartparser.py +5 -5
  8. plain/http/request.py +5 -5
  9. plain/http/response.py +14 -14
  10. plain/internal/files/locks.py +1 -0
  11. plain/internal/files/move.py +1 -2
  12. plain/internal/files/uploadhandler.py +1 -0
  13. plain/internal/files/utils.py +3 -3
  14. plain/internal/handlers/base.py +3 -7
  15. plain/internal/handlers/exception.py +1 -3
  16. plain/internal/handlers/wsgi.py +1 -1
  17. plain/internal/middleware/slash.py +5 -8
  18. plain/packages/config.py +9 -15
  19. plain/packages/registry.py +12 -12
  20. plain/paginator.py +1 -2
  21. plain/preflight/messages.py +3 -10
  22. plain/preflight/registry.py +2 -2
  23. plain/preflight/urls.py +4 -4
  24. plain/runtime/global_settings.py +1 -0
  25. plain/signing.py +4 -4
  26. plain/test/client.py +14 -13
  27. plain/urls/base.py +1 -1
  28. plain/urls/conf.py +2 -1
  29. plain/urls/resolvers.py +20 -33
  30. plain/utils/cache.py +1 -0
  31. plain/utils/crypto.py +2 -1
  32. plain/utils/datastructures.py +2 -2
  33. plain/utils/dateformat.py +13 -12
  34. plain/utils/dateparse.py +1 -1
  35. plain/utils/decorators.py +1 -1
  36. plain/utils/html.py +7 -7
  37. plain/utils/http.py +8 -8
  38. plain/utils/ipv6.py +1 -1
  39. plain/utils/module_loading.py +2 -2
  40. plain/utils/regex_helper.py +7 -6
  41. plain/utils/termcolors.py +4 -4
  42. plain/utils/text.py +7 -7
  43. plain/utils/timesince.py +1 -1
  44. plain/utils/timezone.py +5 -5
  45. plain/validators.py +1 -3
  46. plain/views/forms.py +2 -2
  47. {plain-0.13.1.dist-info → plain-0.13.2.dist-info}/METADATA +7 -12
  48. {plain-0.13.1.dist-info → plain-0.13.2.dist-info}/RECORD +54 -54
  49. {plain-0.13.1.dist-info → plain-0.13.2.dist-info}/WHEEL +1 -1
  50. plain-0.13.2.dist-info/entry_points.txt +2 -0
  51. plain-0.13.1.dist-info/entry_points.txt +0 -3
  52. {plain-0.13.1.dist-info → plain-0.13.2.dist-info/licenses}/LICENSE +0 -0
plain/utils/text.py CHANGED
@@ -53,7 +53,7 @@ def wrap(text, width):
53
53
  yield line
54
54
  line = ""
55
55
  break
56
- yield "%s\n" % line[: space - 1]
56
+ yield f"{line[: space - 1]}\n"
57
57
  line = line[space:]
58
58
  max_width = min((line.endswith("\n") and width + 1 or width), width)
59
59
  if line:
@@ -224,7 +224,7 @@ class Truncator(SimpleLazyObject):
224
224
  out += truncate_text
225
225
  # Close any tags still open
226
226
  for tag in open_tags:
227
- out += "</%s>" % tag
227
+ out += f"</{tag}>"
228
228
  # Return string
229
229
  return out
230
230
 
@@ -242,7 +242,7 @@ def get_valid_filename(name):
242
242
  s = str(name).strip().replace(" ", "_")
243
243
  s = re.sub(r"(?u)[^-\w.]", "", s)
244
244
  if s in {"", ".", ".."}:
245
- raise SuspiciousFileOperation("Could not derive file name from '%s'" % name)
245
+ raise SuspiciousFileOperation(f"Could not derive file name from '{name}'")
246
246
  return s
247
247
 
248
248
 
@@ -407,9 +407,9 @@ def unescape_string_literal(s):
407
407
  "'ab' c"
408
408
  """
409
409
  if not s or s[0] not in "\"'" or s[-1] != s[0]:
410
- raise ValueError("Not a string literal: %r" % s)
410
+ raise ValueError(f"Not a string literal: {s!r}")
411
411
  quote = s[0]
412
- return s[1:-1].replace(r"\%s" % quote, quote).replace(r"\\", "\\")
412
+ return s[1:-1].replace(rf"\{quote}", quote).replace(r"\\", "\\")
413
413
 
414
414
 
415
415
  @keep_lazy_text
@@ -475,9 +475,9 @@ def pluralize_lazy(singular, plural, number):
475
475
  return values[number]
476
476
  except KeyError:
477
477
  raise KeyError(
478
- "Your dictionary lacks key '%s'. Please provide "
478
+ f"Your dictionary lacks key '{number}'. Please provide "
479
479
  "it, because it is required to determine whether "
480
- "string is singular or plural." % number
480
+ "string is singular or plural."
481
481
  )
482
482
 
483
483
  def _translate(self, number_value):
plain/utils/timesince.py CHANGED
@@ -63,7 +63,7 @@ def timesince(d, now=None, reversed=False, time_strings=None, depth=2):
63
63
  if now and not isinstance(now, datetime.datetime):
64
64
  now = datetime.datetime(now.year, now.month, now.day)
65
65
 
66
- now = now or datetime.datetime.now(datetime.timezone.utc if is_aware(d) else None)
66
+ now = now or datetime.datetime.now(datetime.UTC if is_aware(d) else None)
67
67
 
68
68
  if reversed:
69
69
  d, now = now, d
plain/utils/timezone.py CHANGED
@@ -5,7 +5,7 @@ Timezone-related classes and functions.
5
5
  import functools
6
6
  import zoneinfo
7
7
  from contextlib import ContextDecorator
8
- from datetime import datetime, timedelta, timezone, tzinfo
8
+ from datetime import UTC, datetime, timedelta, timezone, tzinfo
9
9
  from threading import local
10
10
 
11
11
  from plain.runtime import settings
@@ -33,7 +33,7 @@ def get_fixed_timezone(offset):
33
33
  if isinstance(offset, timedelta):
34
34
  offset = offset.total_seconds() // 60
35
35
  sign = "-" if offset < 0 else "+"
36
- hhmm = "%02d%02d" % divmod(abs(offset), 60)
36
+ hhmm = "%02d%02d" % divmod(abs(offset), 60) # noqa: UP031
37
37
  name = sign + hhmm
38
38
  return timezone(timedelta(minutes=offset), name)
39
39
 
@@ -95,7 +95,7 @@ def activate(timezone):
95
95
  elif isinstance(timezone, str):
96
96
  _active.value = zoneinfo.ZoneInfo(timezone)
97
97
  else:
98
- raise ValueError("Invalid timezone: %r" % timezone)
98
+ raise ValueError(f"Invalid timezone: {timezone!r}")
99
99
 
100
100
 
101
101
  def deactivate():
@@ -165,7 +165,7 @@ def now():
165
165
  """
166
166
  Return a timezone aware datetime.
167
167
  """
168
- return datetime.now(tz=timezone.utc)
168
+ return datetime.now(tz=UTC)
169
169
 
170
170
 
171
171
  # By design, these four functions don't perform any checks on their arguments.
@@ -204,7 +204,7 @@ def make_aware(value, timezone=None):
204
204
  timezone = get_current_timezone()
205
205
  # Check that we won't overwrite the timezone of an aware datetime.
206
206
  if is_aware(value):
207
- raise ValueError("make_aware expects a naive datetime, got %s" % value)
207
+ raise ValueError(f"make_aware expects a naive datetime, got {value}")
208
208
  # This may be wrong around DST changes!
209
209
  return value.replace(tzinfo=timezone)
210
210
 
plain/validators.py CHANGED
@@ -314,9 +314,7 @@ def ip_address_validators(protocol, unpack_ipv4):
314
314
  return ip_address_validator_map[protocol.lower()]
315
315
  except KeyError:
316
316
  raise ValueError(
317
- "The protocol '{}' is unknown. Supported: {}".format(
318
- protocol, list(ip_address_validator_map)
319
- )
317
+ f"The protocol '{protocol}' is unknown. Supported: {list(ip_address_validator_map)}"
320
318
  )
321
319
 
322
320
 
plain/views/forms.py CHANGED
@@ -20,8 +20,8 @@ class FormView(TemplateView):
20
20
  """Return an instance of the form to be used in this view."""
21
21
  if not self.form_class:
22
22
  raise ImproperlyConfigured(
23
- "No form class provided. Define {cls}.form_class or override "
24
- "{cls}.get_form().".format(cls=self.__class__.__name__)
23
+ f"No form class provided. Define {self.__class__.__name__}.form_class or override "
24
+ f"{self.__class__.__name__}.get_form()."
25
25
  )
26
26
  return self.form_class(**self.get_form_kwargs())
27
27
 
@@ -1,16 +1,12 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: plain
3
- Version: 0.13.1
3
+ Version: 0.13.2
4
4
  Summary: A web framework for building products with Python.
5
- Author: Dave Gaeddert
6
- Author-email: dave.gaeddert@dropseed.dev
7
- Requires-Python: >=3.11,<4.0
8
- Classifier: Programming Language :: Python :: 3
9
- Classifier: Programming Language :: Python :: 3.11
10
- Classifier: Programming Language :: Python :: 3.12
11
- Classifier: Programming Language :: Python :: 3.13
12
- Requires-Dist: click (>=8.0.0)
13
- Requires-Dist: jinja2 (>=3.1.2,<4.0.0)
5
+ Author-email: Dave Gaeddert <dave.gaeddert@dropseed.dev>
6
+ License-File: LICENSE
7
+ Requires-Python: >=3.11
8
+ Requires-Dist: click>=8.0.0
9
+ Requires-Dist: jinja2>=3.1.2
14
10
  Description-Content-Type: text/markdown
15
11
 
16
12
  <!-- This file is compiled from plain/plain/README.md. Do not edit this file directly. -->
@@ -48,4 +44,3 @@ With the official Plain ecosystem packages you can:
48
44
  - Build [staff tooling and admin dashboards](https://plainframework.com/docs/plain-staff/)
49
45
 
50
46
  Learn more at [plainframework.com](https://plainframework.com).
51
-
@@ -1,5 +1,12 @@
1
1
  plain/README.md,sha256=mFsLBpqiHvuznV98eewupvo1JoQeQG0q87wNlXit21A,1695
2
2
  plain/__main__.py,sha256=BiYbF-txGNbeRqp_CHQ9EZ_bCbbKq2iw51Z8RRUgIBY,105
3
+ plain/debug.py,sha256=NxiWJHB4Gi5JfJ4cnxzl-PZ6IgpSnUxg7a_dTQNq_lQ,705
4
+ plain/exceptions.py,sha256=pPAO8cIzNoqa2YrxG0d31C4P2V9SZ2OprHcjY9-qhIU,6332
5
+ plain/json.py,sha256=McJdsbMT1sYwkGRG--f2NSZz0hVXPMix9x3nKaaak2o,1262
6
+ plain/paginator.py,sha256=zCHCmCG8FEet6C28w2rUko9yiGFnOGCQxRbM_ssa9XY,6037
7
+ plain/signing.py,sha256=sf7g1Mp-FzdjFAEoLxHyu2YvbUl5w4FOtTVDAfq6TO0,8733
8
+ plain/validators.py,sha256=2tZh2Bvp955gejltwVtFGwfqw5-9VAOhKqos3Me4paY,19923
9
+ plain/wsgi.py,sha256=R6k5FiAElvGDApEbMPTT0MPqSD7n2e2Az5chQqJZU0I,236
3
10
  plain/assets/README.md,sha256=048BzyQ2-BcsRiv6NiuLHHijOw96RK-e6lJ_Eq7g2pc,2857
4
11
  plain/assets/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
12
  plain/assets/compile.py,sha256=lsnciN85YjHe6d8VIKJi1L8r7NGHNzMOe9L87wObM5I,3287
@@ -7,49 +14,46 @@ plain/assets/finders.py,sha256=WEKAnXTmpuQ7UKLZz7vHPrKFdDOkuZSP6_JTKmIxrKg,1268
7
14
  plain/assets/fingerprints.py,sha256=1NKAnnXVlncY5iimXztr0NL3RIjBKsNlZRIe6nmItJc,931
8
15
  plain/assets/urls.py,sha256=ZTIoM1Zq35JaXZ3wFhXhfGa7VoITDNlH9i5RS0R5xow,933
9
16
  plain/assets/views.py,sha256=dhjIpMu0GDR_VGbXM90_6RnC84C2C4bFv1RxDVklGBk,9173
10
- plain/cli/README.md,sha256=xjr1K-sIMTi5OWxdxL--O7aoo16Pd1xdawIZtz6BL7Q,2464
17
+ plain/cli/README.md,sha256=TvWCnNwb1rNthPzJglCRMKacN5H_RLeEjYBMe62Uz4M,2461
11
18
  plain/cli/__init__.py,sha256=9ByBOIdM8DebChjNz-RH2atdz4vWe8somlwNEsbhwh4,40
12
- plain/cli/cli.py,sha256=o3h6ZQLvxytNwuzTUjRg-TbNw6_FrTBgbmYxjBt6CuI,14543
19
+ plain/cli/cli.py,sha256=Y6QLN114ABuDBEy4heBBXLyfhkYvMopmFCcDy_O6ZKk,14537
13
20
  plain/cli/formatting.py,sha256=1hZH13y1qwHcU2K2_Na388nw9uvoeQH8LrWL-O9h8Yc,2207
14
21
  plain/cli/packages.py,sha256=69VH1bIi1-5N5l2jlBcR5EP0pt-v16sPar9arO3gCSE,2052
15
22
  plain/cli/print.py,sha256=XraUYrgODOJquIiEv78wSCYGRBplHXtXSS9QtFG5hqY,217
16
- plain/cli/startup.py,sha256=PJYA-tNWGia-QbTlT0e5HvC8C7yDSq8wkAkIxgfKkvw,680
23
+ plain/cli/startup.py,sha256=3LIz9JrIZoF52Sa0j0SCypQwEaBDkhvuGaBdtiQLr5Q,680
17
24
  plain/csrf/README.md,sha256=RXMWMtHmzf30gVVNOfj0kD4xlSqFIPgJh-n7dIciaEM,163
18
- plain/csrf/middleware.py,sha256=MlDQ55B4eRXySbzauFNs8gKhgQy32yWspBfPI0a3PzA,17775
25
+ plain/csrf/middleware.py,sha256=pD9un9oLK6YNAEPW0rsVDsHyhyxmAA_IDE5hXs6mHiA,17776
19
26
  plain/csrf/views.py,sha256=YDgT451X16iUdCxpQ6rcHIy7nD0u7DAvCQl5-Mx5i9Y,219
20
- plain/debug.py,sha256=NxiWJHB4Gi5JfJ4cnxzl-PZ6IgpSnUxg7a_dTQNq_lQ,705
21
- plain/exceptions.py,sha256=tDS6l0epe_L9IlxpEdT2k2hWgEoAu8YBNIumNCtJ-WY,6333
22
27
  plain/forms/README.md,sha256=fglB9MmHiEgfGGdZmcRstNl6eYaFljrElu2mzapK52M,377
23
28
  plain/forms/__init__.py,sha256=UxqPwB8CiYPCQdHmUc59jadqaXqDmXBH8y4bt9vTPms,226
24
29
  plain/forms/boundfield.py,sha256=LhydhCVR0okrli0-QBMjGjAJ8-06gTCXVEaBZhBouQk,1741
25
30
  plain/forms/exceptions.py,sha256=XCLDRl5snIEDu5-8mLB0NnU_tegcBfyIHMiJxqvbxnc,164
26
31
  plain/forms/fields.py,sha256=86ZE9jac6Zyg5vKsYGgyOUOIQLKxO--UomGXwA65tk4,35103
27
- plain/forms/forms.py,sha256=-EcS2QVpAy4H95Y-RL108LnWnHLSyCGgEnUCdIIXnjg,10451
32
+ plain/forms/forms.py,sha256=CiONLo9VhE7E1-u-UejX4XWxxwu6MvR-lVPaVAY7VQM,10441
28
33
  plain/http/README.md,sha256=00zLFQ-FPjYXu3A8QsLhCCXxaT0ImvI5I-8xd3dp8WA,7
29
34
  plain/http/__init__.py,sha256=DIsDRbBsCGa4qZgq-fUuQS0kkxfbTU_3KpIM9VvH04w,1067
30
35
  plain/http/cookie.py,sha256=11FnSG3Plo6T3jZDbPoCw7SKh9ExdBio3pTmIO03URg,597
31
- plain/http/multipartparser.py,sha256=Z2PFDuGucj_nFnQagwdxowJcZHqzCfDApkXl5yRlRe4,27325
32
- plain/http/request.py,sha256=kOXN9uhgtgbd1IC25-oRupYlCofacE1jyoDZRlg2v5k,25990
33
- plain/http/response.py,sha256=h43Gx4PVPGEf63EHHrABYtwYu-8Y9mgAebwiGt8qeLE,24074
36
+ plain/http/multipartparser.py,sha256=k6BhpilFENQQ1cuGix6aa-jGwbhBVms2A2O01-s3_4c,27304
37
+ plain/http/request.py,sha256=sqE83ZaB1P2i7iEUQ6d-K_6X4xhpdRdsPiTVraiDoNU,25984
38
+ plain/http/response.py,sha256=wWZhz4AC6imR6-MI9P5TjaZKWRrxjLhSba9vqP-Iflc,24110
34
39
  plain/internal/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
35
40
  plain/internal/files/README.md,sha256=kMux-NU5qiH0o1K8IajYQT8VjrYl_jLk9LkGG_kGuSc,45
36
41
  plain/internal/files/__init__.py,sha256=VctFgox4Q1AWF3klPaoCC5GIw5KeLafYjY5JmN8mAVw,63
37
42
  plain/internal/files/base.py,sha256=CSq_BPKWY2kUib7pnoIvzi40isEyrKdkx1yHb8nPtLc,4817
38
- plain/internal/files/locks.py,sha256=FaRze8qXnHFNVv9w7wLw8XAMBJGTQPKLg1j5l89r0HI,3615
39
- plain/internal/files/move.py,sha256=UK5ureNamr8lh7EvOvo6SqrUa-9MKHT44qgVktPmD5Q,3256
43
+ plain/internal/files/locks.py,sha256=z03q7IZD4tPMK3s1HKF3w_uetkFj6w6FTheLUxZsfB0,3616
44
+ plain/internal/files/move.py,sha256=jfdD29QhamxZjXRgqmZS4dJoJ4sK6M7QK1Km-69jWeo,3238
40
45
  plain/internal/files/temp.py,sha256=UJJnCI8dqPIC8XXHU3-jG2-0svbkrgGlBs4yhciLm4c,2506
41
46
  plain/internal/files/uploadedfile.py,sha256=JRB7T3quQjg-1y3l1ASPxywtSQZhaeMc45uFPIxvl7c,4192
42
- plain/internal/files/uploadhandler.py,sha256=BZGQDHJMEUeBh9uJtxNVWQkFmHE7jzVTx9CLVt59Jqg,7197
43
- plain/internal/files/utils.py,sha256=XrHAs2tMqmywURgz5C6-GSj6sr2R-MCERcWT8yzBp5k,2652
47
+ plain/internal/files/uploadhandler.py,sha256=eEnd5onstypjHYtg367PnVWwCaF1kAPlLPSV7goIf_E,7198
48
+ plain/internal/files/utils.py,sha256=xN4HTJXDRdcoNyrL1dFd528MBwodRlHZM8DGTD_oBIg,2646
44
49
  plain/internal/handlers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
45
- plain/internal/handlers/base.py,sha256=tpTrVhC_gZKrIoTJmCWD3bIpucOCGVV1DTkF0W2HZPI,4883
46
- plain/internal/handlers/exception.py,sha256=KUZSBzmzE6YSFxAZ336Mye_9vAPVIj9Av-w1SK5R4PA,4579
47
- plain/internal/handlers/wsgi.py,sha256=WIZvXlEAOn8lxwDM_HpSP82-ePKVu-Tzgpe65KkXEMk,7538
50
+ plain/internal/handlers/base.py,sha256=I6549DBZUb-anqox7arzL9wpypH4bUCxZkitO76hljI,4794
51
+ plain/internal/handlers/exception.py,sha256=DH9gh1FyqgetFpMaB8yLIVE6phBTVPKQLA1GIn9MOeI,4555
52
+ plain/internal/handlers/wsgi.py,sha256=EWoH9EeetfgiL0BtoAe2Aof0VWaBrxl74Y9EP4xx0wc,7553
48
53
  plain/internal/middleware/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
49
54
  plain/internal/middleware/headers.py,sha256=UnJWnlVVLD-10h7PB_QSYeREBzLo-TS3C-_ahmZ6w0I,636
50
55
  plain/internal/middleware/https.py,sha256=XpuQK8HicYX1jNanQHqNgyQ9rqe4NLUOZO3ZzKdsP8k,1203
51
- plain/internal/middleware/slash.py,sha256=LhQi5aUztE4kJnvRn75u8zaFvAVPPEl_Whu1gYWGs7g,2656
52
- plain/json.py,sha256=McJdsbMT1sYwkGRG--f2NSZz0hVXPMix9x3nKaaak2o,1262
56
+ plain/internal/middleware/slash.py,sha256=1rZsSSzXAA-vBb-dc2RlZaKW9gTT8YM8fJzwYGL4swA,2575
53
57
  plain/logs/README.md,sha256=H6uVXdInYlasq0Z1WnhWnPmNwYQoZ1MSLPDQ4ZE7u4A,492
54
58
  plain/logs/__init__.py,sha256=rASvo4qFBDIHfkACmGLNGa6lRGbG9PbNjW6FmBt95ys,168
55
59
  plain/logs/configure.py,sha256=6mV7d1IxkDYT3VBz61qhIj0Esuy5l5QdQfsHaGCfI6w,1063
@@ -57,26 +61,24 @@ plain/logs/loggers.py,sha256=iz9SYcwP9w5QAuwpULl48SFkVyJuuMoQ_fdLgdCHpNg,2121
57
61
  plain/logs/utils.py,sha256=9UzdCCQXJinGDs71Ngw297mlWkhgZStSd67ya4NOW98,1257
58
62
  plain/packages/README.md,sha256=Vq1Nw3mmEmZ2IriQavuVi4BjcQC2nb8k7YIbnm8QjIg,799
59
63
  plain/packages/__init__.py,sha256=DnHN1wwHXiXib4Y9BV__x9WrbUaTovoTIxW-tVyScTU,106
60
- plain/packages/config.py,sha256=6Vdf1TEQllZkkEvK0WK__zHJYT9nxmS3EyYrbuq0GkM,11201
61
- plain/packages/registry.py,sha256=Bihdu1sOVslmb2CHAJbMqqzsLIPn0FkqwHoD_JrfZy4,17936
62
- plain/paginator.py,sha256=4v5SbYotJH9HoNdzf-1j-AEy4ZLbLPuysf-VME4-6e0,6055
64
+ plain/packages/config.py,sha256=-je13ViDkXMEQXCSi0G539dG5_HPoFBKaK7cBEd_NAY,11070
65
+ plain/packages/registry.py,sha256=C1yv-JlzMs4HE-AYam_EdiTKNQwE8IN4qgt22PKxHDE,17920
63
66
  plain/preflight/README.md,sha256=fgcfVRD6rq7IO8AffQhk49c-6akxaE8MQidRp69InDQ,59
64
67
  plain/preflight/__init__.py,sha256=H-TNRvaddPtOGmv4RXoc1fxDV1AOb7_K3u7ECF8mV58,607
65
68
  plain/preflight/files.py,sha256=wbHCNgps7o1c1zQNBd8FDCaVaqX90UwuvLgEQ_DbUpY,510
66
- plain/preflight/messages.py,sha256=u0oc7q7YmBlKYJRcF5SQpzncfOkEzDhZTcpyclQDfHg,2427
67
- plain/preflight/registry.py,sha256=ZpxnZPIklXuT8xZVTxCUp_IER3zhd7DdfsmqIpAbLj4,2306
69
+ plain/preflight/messages.py,sha256=HwatjA6MRFfzFAnSOa_uAw1Pvk_CLuNfW3IYi71_1Mk,2322
70
+ plain/preflight/registry.py,sha256=7s7f_iEwURzv-Ye515P5lJWcHltd5Ca2fsX1Wpbf1wQ,2306
68
71
  plain/preflight/security.py,sha256=sNpv5AHobPcaO48cOUGRNe2EjusTducjY8vyShR8EhI,2645
69
- plain/preflight/urls.py,sha256=O4PQ_v205VA2872fQlhPfxaihDDRCsVp0ZVKQ92aX4k,3019
72
+ plain/preflight/urls.py,sha256=VjK_B6tg22ugPO5VLY9gBCkDPW0mhcRr-64iv_12zCw,3003
70
73
  plain/runtime/README.md,sha256=Q8VVO7JRGuYrDxzuYL6ptoilhclbecxKzpRXKgbWGkU,2061
71
74
  plain/runtime/__init__.py,sha256=DH8TwKTGJhjviOy4yh_d051v8YGaAWMlFBPhK8ZuC9g,1499
72
- plain/runtime/global_settings.py,sha256=-tr_nUT7iwZpvQlCI6AmJsLRoakBYGp2O2ZsCXgye9U,5498
75
+ plain/runtime/global_settings.py,sha256=T871IxXVARnpvxLOGh2YT0PTmafxcH18TuPUNNTE8vo,5499
73
76
  plain/runtime/user_settings.py,sha256=-1xXUggueuOF3YlgnLfeyG55CUvR3azOGWr2UkTOmfs,11259
74
77
  plain/signals/README.md,sha256=cd3tKEgH-xc88CUWyDxl4-qv-HBXx8VT32BXVwA5azA,230
75
78
  plain/signals/__init__.py,sha256=eAs0kLqptuP6I31dWXeAqRNji3svplpAV4Ez6ktjwXM,131
76
79
  plain/signals/dispatch/__init__.py,sha256=FzEygqV9HsM6gopio7O2Oh_X230nA4d5Q9s0sUjMq0E,292
77
80
  plain/signals/dispatch/dispatcher.py,sha256=VxSlqn9PCOTghPPJLOqZPs6FNQZfV2BJpMfFMSg6Dtc,11531
78
81
  plain/signals/dispatch/license.txt,sha256=o9EhDhsC4Q5HbmD-IfNGVTEkXtNE33r5rIt3lleJ8gc,1727
79
- plain/signing.py,sha256=V6A6PTDYWekuwtQRI1iFD8dud5OHPZTv4EkeoZEHoXo,8737
80
82
  plain/templates/README.md,sha256=VfA2HmrklG5weE1md85q9g84cWnMBEiXAynKzM7S1Sk,464
81
83
  plain/templates/__init__.py,sha256=bX76FakE9T7mfK3N0deN85HlwHNQpeigytSC9Z8LcOs,451
82
84
  plain/templates/core.py,sha256=iw58EAmyyv8N5HDA-Sq4-fLgz_qx8v8WJfurgR116jw,625
@@ -88,59 +90,57 @@ plain/templates/jinja/filters.py,sha256=3KJKKbxcv9dLzUDWPcaa88k3NU2m1GG3iMIgFhzX
88
90
  plain/templates/jinja/globals.py,sha256=qhvQuikkRkOTpHSW5FwdsvoViJNlRgHq3-O7ZyeajsE,669
89
91
  plain/test/README.md,sha256=Zso3Ir7a8vQerzKB6egjROQWkpveLAbscn7VTROPAiU,37
90
92
  plain/test/__init__.py,sha256=rXe88Y602NP8DBnReSyXb7dUzKoWweLuT43j-qwOUl4,138
91
- plain/test/client.py,sha256=470yny2wfLEebdVjQckBqC9pqyDkHy8e0EH-rlVjsAQ,31368
93
+ plain/test/client.py,sha256=xKhpLoA9c0rvEUrfuiewS9_xnCKBrkcump1-pAReQWo,31380
92
94
  plain/urls/README.md,sha256=pWnCvgYkWN7rG7hSyBOtX4ZUP3iO7FhqM6lvwwYll6c,33
93
95
  plain/urls/__init__.py,sha256=3UzwIufXjIks2K_X_Vms2MV19IqvyPLrXUeHU3WP47c,753
94
- plain/urls/base.py,sha256=ECaOCEXs1ygKn4k1mt5XxSNPNlg5raJvx0aPaj7DFfE,3719
95
- plain/urls/conf.py,sha256=l-xh_MdoMYScUHYjp0OQT-YGZ6wMaVnEK_TYwZWJvNM,3475
96
+ plain/urls/base.py,sha256=Q1TzI5WvqYkN1U81fDom1q-AID4dXbszEMF6wAeTAI0,3717
97
+ plain/urls/conf.py,sha256=3R2dCr4iryMPXgUZqESZvqrhTLa5I7PzNY98SuCYYec,3491
96
98
  plain/urls/converters.py,sha256=s2JZVOdzZC16lgobsI93hygcdH5L0Kj4742WEkXsVcs,1193
97
99
  plain/urls/exceptions.py,sha256=q4iPh3Aa-zHbA-tw8v6WyX1J1n5WdAady2xvxFuyXB0,114
98
- plain/urls/resolvers.py,sha256=lDQ1ZpIxE9ekoJKE5TYUDKMmCtPcM3y-KvSWMuwUCD0,27819
100
+ plain/urls/resolvers.py,sha256=Fb2F1cdTxKDn0ZvNX81zHBglZs_aKMgnFuSIJVxNiUk,27508
99
101
  plain/utils/README.md,sha256=Bf5OG-MkOJDz_U8RGVreDfAI4M4nnPaLtk-LdinxHSc,99
100
102
  plain/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
101
103
  plain/utils/_os.py,sha256=oqfiKZRbmHwwWSZP36SIajQnFDbImbB6gcyK0idAGl4,1988
102
- plain/utils/cache.py,sha256=vJeQOWy_kE7jhgwmYjRTMXFvsOYtuPAhHWCjcxEYioU,11475
104
+ plain/utils/cache.py,sha256=SM0jXxWU3XbaMPkthCsYWDYdZH5eOgGzKUgxV1ISNyE,11476
103
105
  plain/utils/connection.py,sha256=NN7xRhy6qIWuOOhi1x9YdGcFcYhKepTiMUETeEMS0vY,2501
104
- plain/utils/crypto.py,sha256=45K6_vF-wPXhOAaCVi98XlHS3-HruzPptSbFf7f1tPA,2661
105
- plain/utils/datastructures.py,sha256=7Su4facKKCv3ae78Kadb--kynYxA37F47CZtOwrj9GY,10225
106
- plain/utils/dateformat.py,sha256=pppxIDsnLuNw8HhHfVuAC9VUeDXW2-QTh19XZlkxDsY,10039
107
- plain/utils/dateparse.py,sha256=6TeWydNK03lL13TIaXGS_MdRlBdzThlLLI4TSSzy5hY,5360
106
+ plain/utils/crypto.py,sha256=zFDydnaqNMGYFHUc-CAn8f93685a17BhGusAcITH1lI,2662
107
+ plain/utils/datastructures.py,sha256=g4UYTbxIb_n8F9JWMP4dHPwUz71591fHreGATPO4qEc,10240
108
+ plain/utils/dateformat.py,sha256=nsy71l16QuPN0ozGpVlCU5Et101fhk9L38F-wqT5p5I,10203
109
+ plain/utils/dateparse.py,sha256=u9_tF85YteXSjW9KQzNg_pcCEFDZS3EGorCddcWU0vE,5351
108
110
  plain/utils/dates.py,sha256=hSDKz8eIb3W5QjmGiklFZZELB0inYXsfiRUy49Cx-2Q,1226
109
111
  plain/utils/deconstruct.py,sha256=7NwEFIDCiadAArUBFmiErzDgfIgDWeKqqQFDXwSgQoQ,1830
110
- plain/utils/decorators.py,sha256=Ma3cqRpCcVIKXOFrxCVmeuKOiLnToP9QbXsJqllrHOw,3470
112
+ plain/utils/decorators.py,sha256=6pcFQ5TezYZoO5Ys1KnImOsv0nUMsFCdxal-S6brUOc,3468
111
113
  plain/utils/deprecation.py,sha256=qtj33kHEmJU7mGSrNcKidZsMo5W8MN-zrXzUq3aVVy8,131
112
114
  plain/utils/duration.py,sha256=l0Gc41-DeyyAmpdy2XG-YO5UKxMf1NDpWIlQuD5hAn0,1162
113
115
  plain/utils/email.py,sha256=puRTBVuz44YvpnqV3LT4nNIKqdqfY3L8zbDJIkqHk2Y,328
114
116
  plain/utils/encoding.py,sha256=z8c7HxYW6wQiE4csx5Ui3WvzgbDzLGXY2aCP04_GZd4,7900
115
117
  plain/utils/functional.py,sha256=7Z1LuPpS1y0ignX7QDzPq6zJqDZdCf_rFYLRR1rTSG0,14806
116
118
  plain/utils/hashable.py,sha256=uLWobCCh7VcEPJ7xzVGPgigNVuTazYJbyzRzHTCI_wo,739
117
- plain/utils/html.py,sha256=H1qK727hlS5_UFoMQ9US1CDFJ83_43Xvx-NpS3d0t9o,13494
118
- plain/utils/http.py,sha256=fHeYGZcVFv4_AuhbSEGw6EPPMtwp7rE-HUCoMdGq-wU,12725
119
+ plain/utils/html.py,sha256=K8nJSiNRU54htQOfhezZAYspXaDGN3LjOE3SxmnQml8,13513
120
+ plain/utils/http.py,sha256=OmnqW_nYUaFN-pAEwjTEh9AkpfjKGmE51Ge6inNGB10,12710
119
121
  plain/utils/inspect.py,sha256=lhDEOtmSLEub5Jj__MIgW3AyWOEVkaA6doJKKwBhZ6A,2235
120
- plain/utils/ipv6.py,sha256=AqqDWtMaLGW7kyziWy9eP5EI0E4D4ik4031faYGX6PU,1269
122
+ plain/utils/ipv6.py,sha256=pISQ2AIlG8xXlxpphn388q03fq-fOrlu4GZR0YYjQXw,1267
121
123
  plain/utils/itercompat.py,sha256=lacIDjczhxbwG4ON_KfG1H6VNPOGOpbRhnVhbedo2CY,184
122
- plain/utils/module_loading.py,sha256=_Omv4eCFmnQHSkxapweHOqR8OvSqpylbrxgwNcFGYZs,2256
123
- plain/utils/regex_helper.py,sha256=EsaHtNi7pkYRYVTYDm7k39ge7MVbBUD6LIRiO70Iw4Q,12766
124
+ plain/utils/module_loading.py,sha256=CWl7Shoax9Zkevf1pM9PpS_0V69J5Cukjyj078UPCAw,2252
125
+ plain/utils/regex_helper.py,sha256=pAdh_xG52BOyXLsiuIMPFgduUAoWOEje1ZpjhcefxiA,12769
124
126
  plain/utils/safestring.py,sha256=SHGhpbX6FFDKSYOY9zYAgAQX0g0exzRba7dM2bJalWs,1873
125
- plain/utils/termcolors.py,sha256=78MimQMp4Etoh1X1lokOJ6ucxErHtg8z9rxeTtV5nhk,7394
126
- plain/utils/text.py,sha256=QxhJsk_4VrNVUtwwo0DXGTMHJ1x_hrKOqJOxlPB33qc,16596
127
- plain/utils/timesince.py,sha256=essdb0XWBKWmKtIprs-4rO0qKTtsFqZ0Fwn-RTDyhOc,4758
128
- plain/utils/timezone.py,sha256=AZ7lcmUjofUTfQUb08pHXu0u7TDuPJpMRB5lgvE4E0w,6212
127
+ plain/utils/termcolors.py,sha256=7ddeKVzePDMvKqauYlfhPDsXijZlCLONfxSHFE2o9jU,7394
128
+ plain/utils/text.py,sha256=qX7vECGH4Xk96qZRH9A1IyZA-mrJ-j62j3kDcLTdWK0,16586
129
+ plain/utils/timesince.py,sha256=d-9w_fqKS24IrHsh9-UX6SPNwrQvDp6QhZ_aJzM6AKY,4749
130
+ plain/utils/timezone.py,sha256=6u0sE-9RVp0_OCe0Y1KiYYQoq5THWLokZFQYY8jf78g,6221
129
131
  plain/utils/tree.py,sha256=wdWzmfsgc26YDF2wxhAY3yVxXTixQYqYDKE9mL3L3ZY,4383
130
- plain/validators.py,sha256=L9v9KtTe4iZhZVramZdKGf33R5Tt95FCdg2AJD2-2n0,19963
131
132
  plain/views/README.md,sha256=qndsXKyNMnipPlLaAvgQeGxqXknNQwlFh31Yxk8rHp8,5994
132
133
  plain/views/__init__.py,sha256=a-N1nkklVohJTtz0yD1MMaS0g66HviEjsKydNVVjvVc,392
133
134
  plain/views/base.py,sha256=wMkCAbr3XqXyP8dJr-O9atA1-N6K4-cTFflLhSYGOpY,3227
134
135
  plain/views/csrf.py,sha256=gO9npd_Ut_LoYF_u7Qb_ZsPRfSeE3aTPG97XlMp4oEo,724
135
136
  plain/views/errors.py,sha256=Y4oGX4Z6D2COKcDEfINvXE1acE8Ad15KwNNWPs5BCfc,967
136
137
  plain/views/exceptions.py,sha256=b4euI49ZUKS9O8AGAcFfiDpstzkRAuuj_uYQXzWNHME,138
137
- plain/views/forms.py,sha256=hyi2yjPvl0f4thU3pcKUEjqzUAN95yIJSCZAOdgSlF8,2663
138
+ plain/views/forms.py,sha256=qnAj8yZNVM8cfOdRKkY6UakDzwA5W-VYgyd4jmKSKwk,2669
138
139
  plain/views/objects.py,sha256=9QBYyb8PgkRirXCQ8-Pms4_yMzP37dfeL30hWRYmtZg,7909
139
140
  plain/views/redirect.py,sha256=KLnlktzK6ZNMTlaEiZpMKQMEP5zeTgGLJ9BIkIJfwBo,1733
140
141
  plain/views/templates.py,sha256=nF9CcdhhjAyp3LB0RrSYnBaHpHzMfPSw719RCdcXk7o,2007
141
- plain/wsgi.py,sha256=R6k5FiAElvGDApEbMPTT0MPqSD7n2e2Az5chQqJZU0I,236
142
- plain-0.13.1.dist-info/LICENSE,sha256=m0D5O7QoH9l5Vz_rrX_9r-C8d9UNr_ciK6Qwac7o6yo,3175
143
- plain-0.13.1.dist-info/METADATA,sha256=YwduCEEt6PAHfsEylk-zaY-ThC2V_T01w6zPm0R13UQ,2722
144
- plain-0.13.1.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
145
- plain-0.13.1.dist-info/entry_points.txt,sha256=7O1RZTmMasKYB73bfqQcTwIhsXo7RjEIKv2WbtTtOIM,39
146
- plain-0.13.1.dist-info/RECORD,,
142
+ plain-0.13.2.dist-info/METADATA,sha256=OKgwkbINMVjNELMp-qHYsDi9HuGLu5lLXu_fMLszDFk,2518
143
+ plain-0.13.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
144
+ plain-0.13.2.dist-info/entry_points.txt,sha256=DHHprvufgd7xypiBiqMANYRnpJ9xPPYhYbnPGwOkWqE,40
145
+ plain-0.13.2.dist-info/licenses/LICENSE,sha256=m0D5O7QoH9l5Vz_rrX_9r-C8d9UNr_ciK6Qwac7o6yo,3175
146
+ plain-0.13.2.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: poetry-core 1.9.1
2
+ Generator: hatchling 1.27.0
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ plain = plain.cli:cli
@@ -1,3 +0,0 @@
1
- [console_scripts]
2
- plain=plain.cli:cli
3
-