plain 0.40.0__tar.gz → 0.42.0__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 (164) hide show
  1. {plain-0.40.0 → plain-0.42.0}/PKG-INFO +1 -1
  2. {plain-0.40.0 → plain-0.42.0}/plain/internal/handlers/base.py +2 -2
  3. {plain-0.40.0 → plain-0.42.0}/plain/templates/jinja/filters.py +2 -0
  4. {plain-0.40.0 → plain-0.42.0}/plain/urls/patterns.py +5 -38
  5. {plain-0.40.0 → plain-0.42.0}/plain/urls/resolvers.py +14 -65
  6. {plain-0.40.0 → plain-0.42.0}/plain/views/templates.py +1 -0
  7. {plain-0.40.0 → plain-0.42.0}/pyproject.toml +1 -1
  8. {plain-0.40.0 → plain-0.42.0}/.gitignore +0 -0
  9. {plain-0.40.0 → plain-0.42.0}/LICENSE +0 -0
  10. {plain-0.40.0 → plain-0.42.0}/README.md +0 -0
  11. {plain-0.40.0 → plain-0.42.0}/plain/README.md +0 -0
  12. {plain-0.40.0 → plain-0.42.0}/plain/__main__.py +0 -0
  13. {plain-0.40.0 → plain-0.42.0}/plain/assets/README.md +0 -0
  14. {plain-0.40.0 → plain-0.42.0}/plain/assets/__init__.py +0 -0
  15. {plain-0.40.0 → plain-0.42.0}/plain/assets/compile.py +0 -0
  16. {plain-0.40.0 → plain-0.42.0}/plain/assets/finders.py +0 -0
  17. {plain-0.40.0 → plain-0.42.0}/plain/assets/fingerprints.py +0 -0
  18. {plain-0.40.0 → plain-0.42.0}/plain/assets/urls.py +0 -0
  19. {plain-0.40.0 → plain-0.42.0}/plain/assets/views.py +0 -0
  20. {plain-0.40.0 → plain-0.42.0}/plain/chores/README.md +0 -0
  21. {plain-0.40.0 → plain-0.42.0}/plain/chores/__init__.py +0 -0
  22. {plain-0.40.0 → plain-0.42.0}/plain/chores/registry.py +0 -0
  23. {plain-0.40.0 → plain-0.42.0}/plain/cli/README.md +0 -0
  24. {plain-0.40.0 → plain-0.42.0}/plain/cli/__init__.py +0 -0
  25. {plain-0.40.0 → plain-0.42.0}/plain/cli/build.py +0 -0
  26. {plain-0.40.0 → plain-0.42.0}/plain/cli/chores.py +0 -0
  27. {plain-0.40.0 → plain-0.42.0}/plain/cli/core.py +0 -0
  28. {plain-0.40.0 → plain-0.42.0}/plain/cli/docs.py +0 -0
  29. {plain-0.40.0 → plain-0.42.0}/plain/cli/formatting.py +0 -0
  30. {plain-0.40.0 → plain-0.42.0}/plain/cli/preflight.py +0 -0
  31. {plain-0.40.0 → plain-0.42.0}/plain/cli/print.py +0 -0
  32. {plain-0.40.0 → plain-0.42.0}/plain/cli/registry.py +0 -0
  33. {plain-0.40.0 → plain-0.42.0}/plain/cli/scaffold.py +0 -0
  34. {plain-0.40.0 → plain-0.42.0}/plain/cli/settings.py +0 -0
  35. {plain-0.40.0 → plain-0.42.0}/plain/cli/shell.py +0 -0
  36. {plain-0.40.0 → plain-0.42.0}/plain/cli/startup.py +0 -0
  37. {plain-0.40.0 → plain-0.42.0}/plain/cli/urls.py +0 -0
  38. {plain-0.40.0 → plain-0.42.0}/plain/cli/utils.py +0 -0
  39. {plain-0.40.0 → plain-0.42.0}/plain/csrf/README.md +0 -0
  40. {plain-0.40.0 → plain-0.42.0}/plain/csrf/middleware.py +0 -0
  41. {plain-0.40.0 → plain-0.42.0}/plain/csrf/views.py +0 -0
  42. {plain-0.40.0 → plain-0.42.0}/plain/debug.py +0 -0
  43. {plain-0.40.0 → plain-0.42.0}/plain/exceptions.py +0 -0
  44. {plain-0.40.0 → plain-0.42.0}/plain/forms/README.md +0 -0
  45. {plain-0.40.0 → plain-0.42.0}/plain/forms/__init__.py +0 -0
  46. {plain-0.40.0 → plain-0.42.0}/plain/forms/boundfield.py +0 -0
  47. {plain-0.40.0 → plain-0.42.0}/plain/forms/exceptions.py +0 -0
  48. {plain-0.40.0 → plain-0.42.0}/plain/forms/fields.py +0 -0
  49. {plain-0.40.0 → plain-0.42.0}/plain/forms/forms.py +0 -0
  50. {plain-0.40.0 → plain-0.42.0}/plain/http/README.md +0 -0
  51. {plain-0.40.0 → plain-0.42.0}/plain/http/__init__.py +0 -0
  52. {plain-0.40.0 → plain-0.42.0}/plain/http/cookie.py +0 -0
  53. {plain-0.40.0 → plain-0.42.0}/plain/http/multipartparser.py +0 -0
  54. {plain-0.40.0 → plain-0.42.0}/plain/http/request.py +0 -0
  55. {plain-0.40.0 → plain-0.42.0}/plain/http/response.py +0 -0
  56. {plain-0.40.0 → plain-0.42.0}/plain/internal/__init__.py +0 -0
  57. {plain-0.40.0 → plain-0.42.0}/plain/internal/files/__init__.py +0 -0
  58. {plain-0.40.0 → plain-0.42.0}/plain/internal/files/base.py +0 -0
  59. {plain-0.40.0 → plain-0.42.0}/plain/internal/files/locks.py +0 -0
  60. {plain-0.40.0 → plain-0.42.0}/plain/internal/files/move.py +0 -0
  61. {plain-0.40.0 → plain-0.42.0}/plain/internal/files/temp.py +0 -0
  62. {plain-0.40.0 → plain-0.42.0}/plain/internal/files/uploadedfile.py +0 -0
  63. {plain-0.40.0 → plain-0.42.0}/plain/internal/files/uploadhandler.py +0 -0
  64. {plain-0.40.0 → plain-0.42.0}/plain/internal/files/utils.py +0 -0
  65. {plain-0.40.0 → plain-0.42.0}/plain/internal/handlers/__init__.py +0 -0
  66. {plain-0.40.0 → plain-0.42.0}/plain/internal/handlers/exception.py +0 -0
  67. {plain-0.40.0 → plain-0.42.0}/plain/internal/handlers/wsgi.py +0 -0
  68. {plain-0.40.0 → plain-0.42.0}/plain/internal/middleware/__init__.py +0 -0
  69. {plain-0.40.0 → plain-0.42.0}/plain/internal/middleware/headers.py +0 -0
  70. {plain-0.40.0 → plain-0.42.0}/plain/internal/middleware/https.py +0 -0
  71. {plain-0.40.0 → plain-0.42.0}/plain/internal/middleware/slash.py +0 -0
  72. {plain-0.40.0 → plain-0.42.0}/plain/json.py +0 -0
  73. {plain-0.40.0 → plain-0.42.0}/plain/logs/README.md +0 -0
  74. {plain-0.40.0 → plain-0.42.0}/plain/logs/__init__.py +0 -0
  75. {plain-0.40.0 → plain-0.42.0}/plain/logs/configure.py +0 -0
  76. {plain-0.40.0 → plain-0.42.0}/plain/logs/loggers.py +0 -0
  77. {plain-0.40.0 → plain-0.42.0}/plain/logs/utils.py +0 -0
  78. {plain-0.40.0 → plain-0.42.0}/plain/packages/README.md +0 -0
  79. {plain-0.40.0 → plain-0.42.0}/plain/packages/__init__.py +0 -0
  80. {plain-0.40.0 → plain-0.42.0}/plain/packages/config.py +0 -0
  81. {plain-0.40.0 → plain-0.42.0}/plain/packages/registry.py +0 -0
  82. {plain-0.40.0 → plain-0.42.0}/plain/paginator.py +0 -0
  83. {plain-0.40.0 → plain-0.42.0}/plain/preflight/README.md +0 -0
  84. {plain-0.40.0 → plain-0.42.0}/plain/preflight/__init__.py +0 -0
  85. {plain-0.40.0 → plain-0.42.0}/plain/preflight/files.py +0 -0
  86. {plain-0.40.0 → plain-0.42.0}/plain/preflight/messages.py +0 -0
  87. {plain-0.40.0 → plain-0.42.0}/plain/preflight/registry.py +0 -0
  88. {plain-0.40.0 → plain-0.42.0}/plain/preflight/security.py +0 -0
  89. {plain-0.40.0 → plain-0.42.0}/plain/preflight/urls.py +0 -0
  90. {plain-0.40.0 → plain-0.42.0}/plain/runtime/README.md +0 -0
  91. {plain-0.40.0 → plain-0.42.0}/plain/runtime/__init__.py +0 -0
  92. {plain-0.40.0 → plain-0.42.0}/plain/runtime/global_settings.py +0 -0
  93. {plain-0.40.0 → plain-0.42.0}/plain/runtime/user_settings.py +0 -0
  94. {plain-0.40.0 → plain-0.42.0}/plain/signals/README.md +0 -0
  95. {plain-0.40.0 → plain-0.42.0}/plain/signals/__init__.py +0 -0
  96. {plain-0.40.0 → plain-0.42.0}/plain/signals/dispatch/__init__.py +0 -0
  97. {plain-0.40.0 → plain-0.42.0}/plain/signals/dispatch/dispatcher.py +0 -0
  98. {plain-0.40.0 → plain-0.42.0}/plain/signals/dispatch/license.txt +0 -0
  99. {plain-0.40.0 → plain-0.42.0}/plain/signing.py +0 -0
  100. {plain-0.40.0 → plain-0.42.0}/plain/templates/README.md +0 -0
  101. {plain-0.40.0 → plain-0.42.0}/plain/templates/__init__.py +0 -0
  102. {plain-0.40.0 → plain-0.42.0}/plain/templates/core.py +0 -0
  103. {plain-0.40.0 → plain-0.42.0}/plain/templates/jinja/__init__.py +0 -0
  104. {plain-0.40.0 → plain-0.42.0}/plain/templates/jinja/environments.py +0 -0
  105. {plain-0.40.0 → plain-0.42.0}/plain/templates/jinja/extensions.py +0 -0
  106. {plain-0.40.0 → plain-0.42.0}/plain/templates/jinja/globals.py +0 -0
  107. {plain-0.40.0 → plain-0.42.0}/plain/test/README.md +0 -0
  108. {plain-0.40.0 → plain-0.42.0}/plain/test/__init__.py +0 -0
  109. {plain-0.40.0 → plain-0.42.0}/plain/test/client.py +0 -0
  110. {plain-0.40.0 → plain-0.42.0}/plain/test/encoding.py +0 -0
  111. {plain-0.40.0 → plain-0.42.0}/plain/test/exceptions.py +0 -0
  112. {plain-0.40.0 → plain-0.42.0}/plain/urls/README.md +0 -0
  113. {plain-0.40.0 → plain-0.42.0}/plain/urls/__init__.py +0 -0
  114. {plain-0.40.0 → plain-0.42.0}/plain/urls/converters.py +0 -0
  115. {plain-0.40.0 → plain-0.42.0}/plain/urls/exceptions.py +0 -0
  116. {plain-0.40.0 → plain-0.42.0}/plain/urls/routers.py +0 -0
  117. {plain-0.40.0 → plain-0.42.0}/plain/urls/utils.py +0 -0
  118. {plain-0.40.0 → plain-0.42.0}/plain/utils/README.md +0 -0
  119. {plain-0.40.0 → plain-0.42.0}/plain/utils/__init__.py +0 -0
  120. {plain-0.40.0 → plain-0.42.0}/plain/utils/cache.py +0 -0
  121. {plain-0.40.0 → plain-0.42.0}/plain/utils/connection.py +0 -0
  122. {plain-0.40.0 → plain-0.42.0}/plain/utils/crypto.py +0 -0
  123. {plain-0.40.0 → plain-0.42.0}/plain/utils/datastructures.py +0 -0
  124. {plain-0.40.0 → plain-0.42.0}/plain/utils/dateparse.py +0 -0
  125. {plain-0.40.0 → plain-0.42.0}/plain/utils/deconstruct.py +0 -0
  126. {plain-0.40.0 → plain-0.42.0}/plain/utils/decorators.py +0 -0
  127. {plain-0.40.0 → plain-0.42.0}/plain/utils/duration.py +0 -0
  128. {plain-0.40.0 → plain-0.42.0}/plain/utils/encoding.py +0 -0
  129. {plain-0.40.0 → plain-0.42.0}/plain/utils/functional.py +0 -0
  130. {plain-0.40.0 → plain-0.42.0}/plain/utils/hashable.py +0 -0
  131. {plain-0.40.0 → plain-0.42.0}/plain/utils/html.py +0 -0
  132. {plain-0.40.0 → plain-0.42.0}/plain/utils/http.py +0 -0
  133. {plain-0.40.0 → plain-0.42.0}/plain/utils/inspect.py +0 -0
  134. {plain-0.40.0 → plain-0.42.0}/plain/utils/ipv6.py +0 -0
  135. {plain-0.40.0 → plain-0.42.0}/plain/utils/itercompat.py +0 -0
  136. {plain-0.40.0 → plain-0.42.0}/plain/utils/module_loading.py +0 -0
  137. {plain-0.40.0 → plain-0.42.0}/plain/utils/regex_helper.py +0 -0
  138. {plain-0.40.0 → plain-0.42.0}/plain/utils/safestring.py +0 -0
  139. {plain-0.40.0 → plain-0.42.0}/plain/utils/text.py +0 -0
  140. {plain-0.40.0 → plain-0.42.0}/plain/utils/timesince.py +0 -0
  141. {plain-0.40.0 → plain-0.42.0}/plain/utils/timezone.py +0 -0
  142. {plain-0.40.0 → plain-0.42.0}/plain/utils/tree.py +0 -0
  143. {plain-0.40.0 → plain-0.42.0}/plain/validators.py +0 -0
  144. {plain-0.40.0 → plain-0.42.0}/plain/views/README.md +0 -0
  145. {plain-0.40.0 → plain-0.42.0}/plain/views/__init__.py +0 -0
  146. {plain-0.40.0 → plain-0.42.0}/plain/views/base.py +0 -0
  147. {plain-0.40.0 → plain-0.42.0}/plain/views/csrf.py +0 -0
  148. {plain-0.40.0 → plain-0.42.0}/plain/views/errors.py +0 -0
  149. {plain-0.40.0 → plain-0.42.0}/plain/views/exceptions.py +0 -0
  150. {plain-0.40.0 → plain-0.42.0}/plain/views/forms.py +0 -0
  151. {plain-0.40.0 → plain-0.42.0}/plain/views/objects.py +0 -0
  152. {plain-0.40.0 → plain-0.42.0}/plain/views/redirect.py +0 -0
  153. {plain-0.40.0 → plain-0.42.0}/plain/wsgi.py +0 -0
  154. {plain-0.40.0 → plain-0.42.0}/tests/.bolt/assets_collected/assets.json +0 -0
  155. {plain-0.40.0 → plain-0.42.0}/tests/.gitignore +0 -0
  156. {plain-0.40.0 → plain-0.42.0}/tests/app/.gitignore +0 -0
  157. {plain-0.40.0 → plain-0.42.0}/tests/app/settings.py +0 -0
  158. {plain-0.40.0 → plain-0.42.0}/tests/app/test/__init__.py +0 -0
  159. {plain-0.40.0 → plain-0.42.0}/tests/app/test/default_settings.py +0 -0
  160. {plain-0.40.0 → plain-0.42.0}/tests/app/urls.py +0 -0
  161. {plain-0.40.0 → plain-0.42.0}/tests/conftest.py +0 -0
  162. {plain-0.40.0 → plain-0.42.0}/tests/test_cli.py +0 -0
  163. {plain-0.40.0 → plain-0.42.0}/tests/test_runtime.py +0 -0
  164. {plain-0.40.0 → plain-0.42.0}/tests/test_wsgi.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: plain
3
- Version: 0.40.0
3
+ Version: 0.42.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
@@ -80,12 +80,12 @@ class BaseHandler:
80
80
  """
81
81
  resolver_match = self.resolve_request(request)
82
82
 
83
- response = resolver_match.func(
83
+ response = resolver_match.view(
84
84
  request, *resolver_match.args, **resolver_match.kwargs
85
85
  )
86
86
 
87
87
  # Complain if the view returned None (a common error).
88
- self.check_response(response, resolver_match.func)
88
+ self.check_response(response, resolver_match.view)
89
89
 
90
90
  return response
91
91
 
@@ -19,6 +19,8 @@ default_filters = {
19
19
  # The standard Python ones
20
20
  "strftime": datetime.datetime.strftime,
21
21
  "strptime": datetime.datetime.strptime,
22
+ "fromtimestamp": datetime.datetime.fromtimestamp,
23
+ "fromisoformat": datetime.datetime.fromisoformat,
22
24
  # To convert to user time zone
23
25
  "localtime": localtime_filter,
24
26
  "timeuntil": timeuntil,
@@ -1,13 +1,10 @@
1
- import functools
2
- import inspect
3
1
  import re
4
2
  import string
5
3
 
6
4
  from plain.exceptions import ImproperlyConfigured
7
5
  from plain.internal import internalcode
8
- from plain.preflight import Error, Warning
6
+ from plain.preflight import Warning
9
7
  from plain.runtime import settings
10
- from plain.utils.functional import cached_property
11
8
  from plain.utils.regex_helper import _lazy_re_compile
12
9
 
13
10
  from .converters import get_converter
@@ -226,20 +223,6 @@ class URLPattern:
226
223
  else:
227
224
  return []
228
225
 
229
- def _check_view(self):
230
- from plain.views import View
231
-
232
- view = self.view
233
- if inspect.isclass(view) and issubclass(view, View):
234
- return [
235
- Error(
236
- f"Your URL pattern {self.pattern.describe()} has an invalid view, pass {view.__name__}.as_view() "
237
- f"instead of {view.__name__}.",
238
- id="urls.E009",
239
- )
240
- ]
241
- return []
242
-
243
226
  def resolve(self, path):
244
227
  match = self.pattern.match(path)
245
228
  if match:
@@ -247,25 +230,9 @@ class URLPattern:
247
230
  from .resolvers import ResolverMatch
248
231
 
249
232
  return ResolverMatch(
250
- self.view,
251
- args,
252
- captured_kwargs,
253
- self.pattern.name,
233
+ view=self.view,
234
+ args=args,
235
+ kwargs=captured_kwargs,
236
+ url_name=self.pattern.name,
254
237
  route=str(self.pattern),
255
- captured_kwargs=captured_kwargs,
256
238
  )
257
-
258
- @cached_property
259
- def lookup_str(self):
260
- """
261
- A string that identifies the view (e.g. 'path.to.view_function' or
262
- 'path.to.ClassBasedView').
263
- """
264
- view = self.view
265
- if isinstance(view, functools.partial):
266
- view = view.func
267
- if hasattr(view, "view_class"):
268
- view = view.view_class
269
- elif not hasattr(view, "__name__"):
270
- return view.__module__ + "." + view.__class__.__name__
271
- return view.__module__ + "." + view.__qualname__
@@ -8,7 +8,6 @@ attributes of the resolved URL match.
8
8
 
9
9
  import functools
10
10
  import re
11
- from pickle import PicklingError
12
11
  from threading import local
13
12
  from urllib.parse import quote
14
13
 
@@ -26,66 +25,29 @@ from .patterns import RegexPattern, URLPattern
26
25
  class ResolverMatch:
27
26
  def __init__(
28
27
  self,
29
- func,
28
+ *,
29
+ view,
30
30
  args,
31
31
  kwargs,
32
32
  url_name=None,
33
33
  namespaces=None,
34
34
  route=None,
35
- tried=None,
36
- captured_kwargs=None,
37
- extra_kwargs=None,
38
35
  ):
39
- self.func = func
36
+ self.view = view
40
37
  self.args = args
41
38
  self.kwargs = kwargs
42
39
  self.url_name = url_name
43
40
  self.route = route
44
- self.tried = tried
45
- self.captured_kwargs = captured_kwargs
46
- self.extra_kwargs = extra_kwargs
47
41
 
48
42
  # If a URLRegexResolver doesn't have a namespace or namespace, it passes
49
43
  # in an empty value.
50
44
  self.namespaces = [x for x in namespaces if x] if namespaces else []
51
45
  self.namespace = ":".join(self.namespaces)
52
46
 
53
- if hasattr(func, "view_class"):
54
- func = func.view_class
55
- if not hasattr(func, "__name__"):
56
- # A class-based view
57
- self._func_path = func.__class__.__module__ + "." + func.__class__.__name__
58
- else:
59
- # A function-based view
60
- self._func_path = func.__module__ + "." + func.__name__
61
-
62
- view_path = url_name or self._func_path
63
- self.view_name = ":".join(self.namespaces + [view_path])
64
-
65
- def __repr__(self):
66
- if isinstance(self.func, functools.partial):
67
- func = repr(self.func)
68
- else:
69
- func = self._func_path
70
- return (
71
- "ResolverMatch(func={}, args={!r}, kwargs={!r}, url_name={!r}, "
72
- "namespaces={!r}, route={!r}{}{})".format(
73
- func,
74
- self.args,
75
- self.kwargs,
76
- self.url_name,
77
- self.namespaces,
78
- self.route,
79
- f", captured_kwargs={self.captured_kwargs!r}"
80
- if self.captured_kwargs
81
- else "",
82
- f", extra_kwargs={self.extra_kwargs!r}" if self.extra_kwargs else "",
83
- )
47
+ self.namespaced_url_name = (
48
+ ":".join(self.namespaces + [url_name]) if url_name else None
84
49
  )
85
50
 
86
- def __reduce_ex__(self, protocol):
87
- raise PicklingError(f"Cannot pickle {self.__class__.__qualname__}.")
88
-
89
51
 
90
52
  def get_resolver(router=None):
91
53
  if router is None:
@@ -257,13 +219,6 @@ class URLResolver:
257
219
  self._populate()
258
220
  return self._app_dict
259
221
 
260
- @staticmethod
261
- def _extend_tried(tried, pattern, sub_tried=None):
262
- if sub_tried is None:
263
- tried.append([pattern])
264
- else:
265
- tried.extend([pattern, *t] for t in sub_tried)
266
-
267
222
  @staticmethod
268
223
  def _join_route(route1, route2):
269
224
  """Join two routes, without the starting ^ in the second route."""
@@ -274,15 +229,14 @@ class URLResolver:
274
229
 
275
230
  def resolve(self, path):
276
231
  path = str(path) # path may be a reverse_lazy object
277
- tried = []
278
232
  match = self.pattern.match(path)
279
233
  if match:
280
234
  new_path, args, kwargs = match
281
235
  for pattern in self.url_patterns:
282
236
  try:
283
237
  sub_match = pattern.resolve(new_path)
284
- except Resolver404 as e:
285
- self._extend_tried(tried, pattern, e.args[0].get("tried"))
238
+ except Resolver404:
239
+ pass
286
240
  else:
287
241
  if sub_match:
288
242
  # Merge captured arguments in match with submatch
@@ -299,20 +253,15 @@ class URLResolver:
299
253
  if isinstance(pattern, URLPattern)
300
254
  else str(pattern.pattern)
301
255
  )
302
- self._extend_tried(tried, pattern, sub_match.tried)
303
256
  return ResolverMatch(
304
- sub_match.func,
305
- sub_match_args,
306
- sub_match_dict,
307
- sub_match.url_name,
308
- [self.namespace] + sub_match.namespaces,
309
- self._join_route(current_route, sub_match.route),
310
- tried,
311
- captured_kwargs=sub_match.captured_kwargs,
312
- extra_kwargs=sub_match.extra_kwargs,
257
+ view=sub_match.view,
258
+ args=sub_match_args,
259
+ kwargs=sub_match_dict,
260
+ url_name=sub_match.url_name,
261
+ namespaces=[self.namespace] + sub_match.namespaces,
262
+ route=self._join_route(current_route, sub_match.route),
313
263
  )
314
- tried.append([pattern])
315
- raise Resolver404({"tried": tried, "path": new_path})
264
+ raise Resolver404({"path": new_path})
316
265
  raise Resolver404({"path": path})
317
266
 
318
267
  def reverse(self, lookup_view, *args, **kwargs):
@@ -35,6 +35,7 @@ class TemplateView(View):
35
35
  def get_template_context(self) -> dict:
36
36
  return {
37
37
  "request": self.request,
38
+ "template_names": self.get_template_names(),
38
39
  "csrf_input": csrf_input_lazy(self.request),
39
40
  "csrf_token": csrf_token_lazy(self.request),
40
41
  "DEBUG": settings.DEBUG,
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "plain"
3
- version = "0.40.0"
3
+ version = "0.42.0"
4
4
  description = "A web framework for building products with Python."
5
5
  authors = [{name = "Dave Gaeddert", email = "dave.gaeddert@dropseed.dev"}]
6
6
  readme = "README.md"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes