plain 0.34.1__py3-none-any.whl → 0.36.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/assets/views.py +3 -3
- plain/cli/build.py +107 -0
- plain/cli/core.py +17 -685
- plain/cli/docs.py +211 -0
- plain/cli/preflight.py +127 -0
- plain/cli/scaffold.py +53 -0
- plain/cli/settings.py +60 -0
- plain/cli/shell.py +56 -0
- plain/cli/startup.py +24 -12
- plain/cli/urls.py +87 -0
- plain/cli/utils.py +15 -0
- plain/csrf/README.md +1 -1
- plain/csrf/middleware.py +3 -3
- plain/http/README.md +1 -1
- plain/http/response.py +15 -9
- plain/runtime/global_settings.py +8 -1
- plain/test/client.py +8 -8
- plain/views/README.md +1 -1
- plain/views/base.py +3 -2
- plain/views/objects.py +3 -65
- plain/views/redirect.py +5 -0
- plain/views/templates.py +11 -9
- {plain-0.34.1.dist-info → plain-0.36.0.dist-info}/METADATA +1 -1
- {plain-0.34.1.dist-info → plain-0.36.0.dist-info}/RECORD +27 -19
- {plain-0.34.1.dist-info → plain-0.36.0.dist-info}/WHEEL +0 -0
- {plain-0.34.1.dist-info → plain-0.36.0.dist-info}/entry_points.txt +0 -0
- {plain-0.34.1.dist-info → plain-0.36.0.dist-info}/licenses/LICENSE +0 -0
plain/csrf/middleware.py
CHANGED
@@ -156,7 +156,7 @@ class RejectRequest(Exception):
|
|
156
156
|
|
157
157
|
class CsrfViewMiddleware:
|
158
158
|
"""
|
159
|
-
Require a present and correct
|
159
|
+
Require a present and correct _csrftoken for POST requests that
|
160
160
|
have a CSRF cookie, and set an outgoing CSRF cookie.
|
161
161
|
|
162
162
|
This middleware should be used in conjunction with the {% csrf_token %}
|
@@ -364,7 +364,7 @@ class CsrfViewMiddleware:
|
|
364
364
|
request_csrf_token = ""
|
365
365
|
if request.method == "POST":
|
366
366
|
try:
|
367
|
-
request_csrf_token = request.POST.get(
|
367
|
+
request_csrf_token = request.POST.get(settings.CSRF_POST_NAME, "")
|
368
368
|
except UnreadablePostError:
|
369
369
|
# Handle a broken connection before we've completed reading the
|
370
370
|
# POST data. process_view shouldn't raise any exceptions, so
|
@@ -380,7 +380,7 @@ class CsrfViewMiddleware:
|
|
380
380
|
# depending on whether the client obtained the token from
|
381
381
|
# the DOM or the cookie (and if the cookie, whether the cookie
|
382
382
|
# was masked or unmasked).
|
383
|
-
request_csrf_token = request.
|
383
|
+
request_csrf_token = request.headers[settings.CSRF_HEADER_NAME]
|
384
384
|
except KeyError:
|
385
385
|
raise RejectRequest(REASON_CSRF_TOKEN_MISSING)
|
386
386
|
token_source = settings.CSRF_HEADER_NAME
|
plain/http/README.md
CHANGED
@@ -17,7 +17,7 @@ class ExampleView(View):
|
|
17
17
|
print(self.request.GET.get("example"))
|
18
18
|
|
19
19
|
# Creating a response
|
20
|
-
response = Response("Hello, world!",
|
20
|
+
response = Response("Hello, world!", status_code=200)
|
21
21
|
|
22
22
|
# Setting a response header
|
23
23
|
response.headers["Example-Header"] = "Example Value"
|
plain/http/response.py
CHANGED
@@ -108,7 +108,13 @@ class ResponseBase:
|
|
108
108
|
status_code = 200
|
109
109
|
|
110
110
|
def __init__(
|
111
|
-
self,
|
111
|
+
self,
|
112
|
+
*,
|
113
|
+
content_type=None,
|
114
|
+
status_code=None,
|
115
|
+
reason=None,
|
116
|
+
charset=None,
|
117
|
+
headers=None,
|
112
118
|
):
|
113
119
|
self.headers = ResponseHeaders(headers)
|
114
120
|
self._charset = charset
|
@@ -127,9 +133,9 @@ class ResponseBase:
|
|
127
133
|
self._handler_class = None
|
128
134
|
self.cookies = SimpleCookie()
|
129
135
|
self.closed = False
|
130
|
-
if
|
136
|
+
if status_code is not None:
|
131
137
|
try:
|
132
|
-
self.status_code = int(
|
138
|
+
self.status_code = int(status_code)
|
133
139
|
except (ValueError, TypeError):
|
134
140
|
raise TypeError("HTTP status code must be an integer.")
|
135
141
|
|
@@ -353,8 +359,8 @@ class Response(ResponseBase):
|
|
353
359
|
]
|
354
360
|
)
|
355
361
|
|
356
|
-
def __init__(self, content=b"",
|
357
|
-
super().__init__(
|
362
|
+
def __init__(self, content=b"", **kwargs):
|
363
|
+
super().__init__(**kwargs)
|
358
364
|
# Content is a bytestring. See the `content` property methods.
|
359
365
|
self.content = content
|
360
366
|
|
@@ -434,8 +440,8 @@ class StreamingResponse(ResponseBase):
|
|
434
440
|
|
435
441
|
streaming = True
|
436
442
|
|
437
|
-
def __init__(self, streaming_content=(),
|
438
|
-
super().__init__(
|
443
|
+
def __init__(self, streaming_content=(), **kwargs):
|
444
|
+
super().__init__(**kwargs)
|
439
445
|
# `streaming_content` should be an iterable of bytestrings.
|
440
446
|
# See the `streaming_content` property methods.
|
441
447
|
self.streaming_content = streaming_content
|
@@ -560,8 +566,8 @@ class FileResponse(StreamingResponse):
|
|
560
566
|
class ResponseRedirectBase(Response):
|
561
567
|
allowed_schemes = ["http", "https", "ftp"]
|
562
568
|
|
563
|
-
def __init__(self, redirect_to,
|
564
|
-
super().__init__(
|
569
|
+
def __init__(self, redirect_to, **kwargs):
|
570
|
+
super().__init__(**kwargs)
|
565
571
|
self.headers["Location"] = iri_to_uri(redirect_to)
|
566
572
|
parsed = urlparse(str(redirect_to))
|
567
573
|
if parsed.scheme and parsed.scheme not in self.allowed_schemes:
|
plain/runtime/global_settings.py
CHANGED
@@ -133,7 +133,8 @@ CSRF_COOKIE_PATH = "/"
|
|
133
133
|
CSRF_COOKIE_SECURE = True
|
134
134
|
CSRF_COOKIE_HTTPONLY = False
|
135
135
|
CSRF_COOKIE_SAMESITE = "Lax"
|
136
|
-
CSRF_HEADER_NAME = "
|
136
|
+
CSRF_HEADER_NAME = "CSRF-Token"
|
137
|
+
CSRF_POST_NAME = "_csrftoken"
|
137
138
|
CSRF_TRUSTED_ORIGINS: list[str] = []
|
138
139
|
|
139
140
|
###########
|
@@ -169,3 +170,9 @@ PREFLIGHT_SILENCED_CHECKS = []
|
|
169
170
|
#############
|
170
171
|
|
171
172
|
TEMPLATES_JINJA_ENVIRONMENT = "plain.templates.jinja.DefaultEnvironment"
|
173
|
+
|
174
|
+
#########
|
175
|
+
# Shell #
|
176
|
+
#########
|
177
|
+
|
178
|
+
SHELL_IMPORT: str = ""
|
plain/test/client.py
CHANGED
@@ -17,7 +17,6 @@ from plain.urls import get_resolver
|
|
17
17
|
from plain.utils.encoding import force_bytes
|
18
18
|
from plain.utils.functional import SimpleLazyObject
|
19
19
|
from plain.utils.http import urlencode
|
20
|
-
from plain.utils.module_loading import import_string
|
21
20
|
from plain.utils.regex_helper import _lazy_re_compile
|
22
21
|
|
23
22
|
from .encoding import encode_multipart
|
@@ -776,11 +775,12 @@ class Client(RequestFactory):
|
|
776
775
|
@property
|
777
776
|
def session(self):
|
778
777
|
"""Return the current session variables."""
|
779
|
-
|
778
|
+
from plain.sessions import SessionStore
|
779
|
+
|
780
780
|
cookie = self.cookies.get(settings.SESSION_COOKIE_NAME)
|
781
781
|
if cookie:
|
782
|
-
return
|
783
|
-
session =
|
782
|
+
return SessionStore(cookie.value)
|
783
|
+
session = SessionStore()
|
784
784
|
session.save()
|
785
785
|
self.cookies[settings.SESSION_COOKIE_NAME] = session.session_key
|
786
786
|
return session
|
@@ -790,14 +790,14 @@ class Client(RequestFactory):
|
|
790
790
|
|
791
791
|
def _login(self, user):
|
792
792
|
from plain.auth import login
|
793
|
+
from plain.sessions import SessionStore
|
793
794
|
|
794
795
|
# Create a fake request to store login details.
|
795
796
|
request = HttpRequest()
|
796
797
|
if self.session:
|
797
798
|
request.session = self.session
|
798
799
|
else:
|
799
|
-
|
800
|
-
request.session = Session()
|
800
|
+
request.session = SessionStore()
|
801
801
|
login(request, user)
|
802
802
|
# Save the session values.
|
803
803
|
request.session.save()
|
@@ -816,14 +816,14 @@ class Client(RequestFactory):
|
|
816
816
|
def logout(self):
|
817
817
|
"""Log out the user by removing the cookies and session object."""
|
818
818
|
from plain.auth import get_user, logout
|
819
|
+
from plain.sessions import SessionStore
|
819
820
|
|
820
821
|
request = HttpRequest()
|
821
822
|
if self.session:
|
822
823
|
request.session = self.session
|
823
824
|
request.user = get_user(request)
|
824
825
|
else:
|
825
|
-
|
826
|
-
request.session = Session()
|
826
|
+
request.session = SessionStore()
|
827
827
|
logout(request)
|
828
828
|
self.cookies = SimpleCookie()
|
829
829
|
|
plain/views/README.md
CHANGED
@@ -214,7 +214,7 @@ class ExampleView(DetailView):
|
|
214
214
|
def get_object(self):
|
215
215
|
if self.request.user.exceeds_rate_limit:
|
216
216
|
raise ResponseException(
|
217
|
-
Response("Rate limit exceeded",
|
217
|
+
Response("Rate limit exceeded", status_code=429)
|
218
218
|
)
|
219
219
|
|
220
220
|
return AnExpensiveObject()
|
plain/views/base.py
CHANGED
@@ -85,7 +85,8 @@ class View:
|
|
85
85
|
return result
|
86
86
|
|
87
87
|
if isinstance(result, str):
|
88
|
-
|
88
|
+
# Assume the str is rendered HTML
|
89
|
+
return Response(result)
|
89
90
|
|
90
91
|
if isinstance(result, list):
|
91
92
|
return JsonResponse(result, safe=False)
|
@@ -94,7 +95,7 @@ class View:
|
|
94
95
|
return JsonResponse(result)
|
95
96
|
|
96
97
|
if isinstance(result, int):
|
97
|
-
return Response(
|
98
|
+
return Response(status_code=result)
|
98
99
|
|
99
100
|
# Allow tuple for (status_code, content)?
|
100
101
|
|
plain/views/objects.py
CHANGED
@@ -7,7 +7,7 @@ from .templates import TemplateView
|
|
7
7
|
|
8
8
|
|
9
9
|
class ObjectTemplateViewMixin:
|
10
|
-
context_object_name = ""
|
10
|
+
context_object_name = "object"
|
11
11
|
|
12
12
|
def get(self) -> Response:
|
13
13
|
self.load_object()
|
@@ -31,39 +31,9 @@ class ObjectTemplateViewMixin:
|
|
31
31
|
def get_template_context(self) -> dict:
|
32
32
|
"""Insert the single object into the context dict."""
|
33
33
|
context = super().get_template_context() # type: ignore
|
34
|
-
context[
|
35
|
-
if self.context_object_name:
|
36
|
-
context[self.context_object_name] = self.object
|
37
|
-
elif hasattr(self.object, "_meta"):
|
38
|
-
context[self.object._meta.model_name] = self.object
|
34
|
+
context[self.context_object_name] = self.object
|
39
35
|
return context
|
40
36
|
|
41
|
-
def get_template_names(self) -> list[str]:
|
42
|
-
"""
|
43
|
-
Return a list of template names to be used for the request. May not be
|
44
|
-
called if render_to_response() is overridden. Return the following list:
|
45
|
-
|
46
|
-
* the value of ``template_name`` on the view (if provided)
|
47
|
-
object instance that the view is operating upon (if available)
|
48
|
-
* ``<package_label>/<model_name><template_name_suffix>.html``
|
49
|
-
"""
|
50
|
-
if self.template_name: # type: ignore
|
51
|
-
return [self.template_name] # type: ignore
|
52
|
-
|
53
|
-
# If template_name isn't specified, it's not a problem --
|
54
|
-
# we just start with an empty list.
|
55
|
-
names = []
|
56
|
-
|
57
|
-
# The least-specific option is the default <app>/<model>_detail.html;
|
58
|
-
# only use this if the object in question is a model.
|
59
|
-
if hasattr(self.object, "_meta"):
|
60
|
-
object_meta = self.object._meta
|
61
|
-
names.append(
|
62
|
-
f"{object_meta.package_label}/{object_meta.model_name}{self.template_name_suffix}.html"
|
63
|
-
)
|
64
|
-
|
65
|
-
return names
|
66
|
-
|
67
37
|
|
68
38
|
class DetailView(ObjectTemplateViewMixin, TemplateView):
|
69
39
|
"""
|
@@ -73,7 +43,7 @@ class DetailView(ObjectTemplateViewMixin, TemplateView):
|
|
73
43
|
view will support display of *any* object by overriding `self.get_object()`.
|
74
44
|
"""
|
75
45
|
|
76
|
-
|
46
|
+
pass
|
77
47
|
|
78
48
|
|
79
49
|
class CreateView(ObjectTemplateViewMixin, FormView):
|
@@ -81,8 +51,6 @@ class CreateView(ObjectTemplateViewMixin, FormView):
|
|
81
51
|
View for creating a new object, with a response rendered by a template.
|
82
52
|
"""
|
83
53
|
|
84
|
-
template_name_suffix = "_form"
|
85
|
-
|
86
54
|
def post(self) -> Response:
|
87
55
|
"""
|
88
56
|
Handle POST requests: instantiate a form instance with the passed
|
@@ -119,8 +87,6 @@ class CreateView(ObjectTemplateViewMixin, FormView):
|
|
119
87
|
class UpdateView(ObjectTemplateViewMixin, FormView):
|
120
88
|
"""View for updating an object, with a response rendered by a template."""
|
121
89
|
|
122
|
-
template_name_suffix = "_form"
|
123
|
-
|
124
90
|
def post(self) -> Response:
|
125
91
|
"""
|
126
92
|
Handle POST requests: instantiate a form instance with the passed
|
@@ -170,7 +136,6 @@ class DeleteView(ObjectTemplateViewMixin, FormView):
|
|
170
136
|
self.instance.delete()
|
171
137
|
|
172
138
|
form_class = EmptyDeleteForm
|
173
|
-
template_name_suffix = "_confirm_delete"
|
174
139
|
|
175
140
|
def post(self) -> Response:
|
176
141
|
"""
|
@@ -198,7 +163,6 @@ class ListView(TemplateView):
|
|
198
163
|
rendered by a template.
|
199
164
|
"""
|
200
165
|
|
201
|
-
template_name_suffix = "_list"
|
202
166
|
context_object_name = "objects"
|
203
167
|
|
204
168
|
def get(self) -> Response:
|
@@ -215,29 +179,3 @@ class ListView(TemplateView):
|
|
215
179
|
context = super().get_template_context() # type: ignore
|
216
180
|
context[self.context_object_name] = self.objects
|
217
181
|
return context
|
218
|
-
|
219
|
-
def get_template_names(self) -> list[str]:
|
220
|
-
"""
|
221
|
-
Return a list of template names to be used for the request. May not be
|
222
|
-
called if render_to_response() is overridden. Return the following list:
|
223
|
-
|
224
|
-
* the value of ``template_name`` on the view (if provided)
|
225
|
-
object instance that the view is operating upon (if available)
|
226
|
-
* ``<package_label>/<model_name><template_name_suffix>.html``
|
227
|
-
"""
|
228
|
-
if self.template_name: # type: ignore
|
229
|
-
return [self.template_name] # type: ignore
|
230
|
-
|
231
|
-
# If template_name isn't specified, it's not a problem --
|
232
|
-
# we just start with an empty list.
|
233
|
-
names = []
|
234
|
-
|
235
|
-
# The least-specific option is the default <app>/<model>_detail.html;
|
236
|
-
# only use this if the object in question is a model.
|
237
|
-
if hasattr(self.objects, "model") and hasattr(self.objects.model, "_meta"):
|
238
|
-
object_meta = self.objects.model._meta
|
239
|
-
names.append(
|
240
|
-
f"{object_meta.package_label}/{object_meta.model_name}{self.template_name_suffix}.html"
|
241
|
-
)
|
242
|
-
|
243
|
-
return names
|
plain/views/redirect.py
CHANGED
@@ -20,6 +20,11 @@ class RedirectView(View):
|
|
20
20
|
pattern_name: str | None = None
|
21
21
|
query_string = False
|
22
22
|
|
23
|
+
def __init__(self, url=None, permanent=None):
|
24
|
+
# Allow url and permanent to be set in RedirectView.as_view(url="...", permanent=True)
|
25
|
+
self.url = url or self.url
|
26
|
+
self.permanent = permanent if permanent is not None else self.permanent
|
27
|
+
|
23
28
|
def get_redirect_url(self):
|
24
29
|
"""
|
25
30
|
Return the URL redirect to. Keyword arguments from the URL pattern
|
plain/views/templates.py
CHANGED
@@ -11,7 +11,8 @@ from .base import View
|
|
11
11
|
|
12
12
|
def csrf_input(request):
|
13
13
|
return format_html(
|
14
|
-
'<input type="hidden" name="
|
14
|
+
'<input type="hidden" name="{}" value="{}">',
|
15
|
+
settings.CSRF_POST_NAME,
|
15
16
|
get_token(request),
|
16
17
|
)
|
17
18
|
|
@@ -41,20 +42,21 @@ class TemplateView(View):
|
|
41
42
|
|
42
43
|
def get_template_names(self) -> list[str]:
|
43
44
|
"""
|
44
|
-
Return a list of template names to be used for the request.
|
45
|
-
a list. May not be called if render_to_response() is overridden.
|
45
|
+
Return a list of template names to be used for the request.
|
46
46
|
"""
|
47
|
-
if self.template_name
|
48
|
-
raise ImproperlyConfigured(
|
49
|
-
"TemplateView requires either a definition of "
|
50
|
-
"'template_name' or an implementation of 'get_template_names()'"
|
51
|
-
)
|
52
|
-
else:
|
47
|
+
if self.template_name:
|
53
48
|
return [self.template_name]
|
54
49
|
|
50
|
+
return []
|
51
|
+
|
55
52
|
def get_template(self) -> Template:
|
56
53
|
template_names = self.get_template_names()
|
57
54
|
|
55
|
+
if not template_names:
|
56
|
+
raise ImproperlyConfigured(
|
57
|
+
f"{self.__class__.__name__} requires a template_name or get_template_names()."
|
58
|
+
)
|
59
|
+
|
58
60
|
for template_name in template_names:
|
59
61
|
try:
|
60
62
|
return Template(template_name)
|
@@ -13,16 +13,24 @@ plain/assets/compile.py,sha256=rABDHj7k_YAIPVvS7JJLCukEgUhb7h5oz9ajt5fGirI,3298
|
|
13
13
|
plain/assets/finders.py,sha256=2k8QZAbfUbc1LykxbzdazTSB6xNxJZnsZaGhWbSFZZs,1452
|
14
14
|
plain/assets/fingerprints.py,sha256=2LPHLUkoITMseLDmemTpBtMRDWCR2H5GAHjC6AN4gz0,1367
|
15
15
|
plain/assets/urls.py,sha256=zQUA8bAlh9qVqskPJJrqWd9DjvetOi5jPSqy4vUX0J4,1161
|
16
|
-
plain/assets/views.py,sha256=
|
16
|
+
plain/assets/views.py,sha256=T_0Qh6v9qBerEBYbhToigwOzsij-x1z_R-1zETQcIh0,9447
|
17
17
|
plain/cli/README.md,sha256=ompPcgzY2Fdpm579ITmCpFIaZIsiXYbfD61mqkq312M,1860
|
18
18
|
plain/cli/__init__.py,sha256=6w9T7K2WrPwh6DcaMb2oNt_CWU6Bc57nUTO2Bt1p38Y,63
|
19
|
-
plain/cli/
|
19
|
+
plain/cli/build.py,sha256=dKUYBNegvb6QNckR7XZ7CJJtINwZcmDvbUdv2dWwjf8,3226
|
20
|
+
plain/cli/core.py,sha256=N7xUO8Ox2xz8wJyWZ0fSyCfqVFmKz9czH9gulRyQuM4,2809
|
21
|
+
plain/cli/docs.py,sha256=dHInHcweVLOew3hCNspVvUQ8epEfovDh3yI6O_FEsnI,7546
|
20
22
|
plain/cli/formatting.py,sha256=1hZH13y1qwHcU2K2_Na388nw9uvoeQH8LrWL-O9h8Yc,2207
|
23
|
+
plain/cli/preflight.py,sha256=NKyYjcoDjigzfJIDhf7A7degYadaUI05Bw7U9OQ73vs,4170
|
21
24
|
plain/cli/print.py,sha256=XraUYrgODOJquIiEv78wSCYGRBplHXtXSS9QtFG5hqY,217
|
22
25
|
plain/cli/registry.py,sha256=yKVMSDjW8g10nlV9sPXFGJQmhC_U-k4J4kM7N2OQVLA,1467
|
23
|
-
plain/cli/
|
24
|
-
plain/
|
25
|
-
plain/
|
26
|
+
plain/cli/scaffold.py,sha256=EEyiexgp9jqmIet3Wndh405xErV0lT1jQevqhGkbudw,1326
|
27
|
+
plain/cli/settings.py,sha256=9cx4bue664I2P7kUedlf4YhCPB0tSKSE4Q8mGyzEv2o,1995
|
28
|
+
plain/cli/shell.py,sha256=iIwvlTdTBjLBBUdXMAmIRWSoynszOZI79-mrBg4RegU,1373
|
29
|
+
plain/cli/startup.py,sha256=wLaFuyUb4ewWhtehBCGicrRCXIIGCRbeCT3ce9hUv-A,1022
|
30
|
+
plain/cli/urls.py,sha256=CS9NFpwZBWveAR8F3YsoUNySDEK_PwF73oSgLDfkOdI,3776
|
31
|
+
plain/cli/utils.py,sha256=VwlIh0z7XxzVV8I3qM2kZo07fkJFPoeeVZa1ODG616k,258
|
32
|
+
plain/csrf/README.md,sha256=Xqb3pRZcIF6TJlOzEksQN0zue4mY7OTebNta9cq0T8g,699
|
33
|
+
plain/csrf/middleware.py,sha256=bn8KOE45aucSam0m3F9g8FVfnmjjt-6jxS6iSNwHamU,17413
|
26
34
|
plain/csrf/views.py,sha256=HwQqfI6KPelHP9gSXhjfZaTLQic71PKsoZ6DPhr1rKI,572
|
27
35
|
plain/forms/README.md,sha256=TawBdy1jP0-8HUsfUzd7vvgkwl3EJGejDxFhWR8F-80,2242
|
28
36
|
plain/forms/__init__.py,sha256=UxqPwB8CiYPCQdHmUc59jadqaXqDmXBH8y4bt9vTPms,226
|
@@ -30,12 +38,12 @@ plain/forms/boundfield.py,sha256=LhydhCVR0okrli0-QBMjGjAJ8-06gTCXVEaBZhBouQk,174
|
|
30
38
|
plain/forms/exceptions.py,sha256=XCLDRl5snIEDu5-8mLB0NnU_tegcBfyIHMiJxqvbxnc,164
|
31
39
|
plain/forms/fields.py,sha256=Fw77LP06aO5h6ZdJmS2S_2On4YSrsl4gu142Y6nGF50,34987
|
32
40
|
plain/forms/forms.py,sha256=fEKBee1b8I_DJ-FufzWJGtSQoUoyieYfqUaGEre9B4Q,10418
|
33
|
-
plain/http/README.md,sha256=
|
41
|
+
plain/http/README.md,sha256=G662f56feQWiEHw9tTncZqK8kNB_nbR1HTGeOR1ygNM,713
|
34
42
|
plain/http/__init__.py,sha256=DIsDRbBsCGa4qZgq-fUuQS0kkxfbTU_3KpIM9VvH04w,1067
|
35
43
|
plain/http/cookie.py,sha256=11FnSG3Plo6T3jZDbPoCw7SKh9ExdBio3pTmIO03URg,597
|
36
44
|
plain/http/multipartparser.py,sha256=Cyk_UZhxf8JwNza_Yl4_nKCYkmnG7xY9PSVcf9Us57U,27266
|
37
45
|
plain/http/request.py,sha256=kq3AuM0EWyAD_kqMlorTccm5mzIQ6ZefkCa-jXUntnI,25514
|
38
|
-
plain/http/response.py,sha256=
|
46
|
+
plain/http/response.py,sha256=IGSg22ioob6kSRkKGQsQF_exb2Lch8RKiZr_Xoi1_xA,23644
|
39
47
|
plain/internal/__init__.py,sha256=fVBaYLCXEQc-7riHMSlw3vMTTuF7-0Bj2I8aGzv0o0w,171
|
40
48
|
plain/internal/files/__init__.py,sha256=VctFgox4Q1AWF3klPaoCC5GIw5KeLafYjY5JmN8mAVw,63
|
41
49
|
plain/internal/files/base.py,sha256=-JpRMzv2bgVSZ9dcxh13gGRTVeEd_Tjd02iQMOXsRgQ,4126
|
@@ -71,7 +79,7 @@ plain/preflight/security.py,sha256=oxUZBp2M0bpBfUoLYepIxoex2Y90nyjlrL8XU8UTHYY,2
|
|
71
79
|
plain/preflight/urls.py,sha256=cQ-WnFa_5oztpKdtwhuIGb7pXEml__bHsjs1SWO2YNI,1468
|
72
80
|
plain/runtime/README.md,sha256=S_FIOmSq8LkVQHh9Xm6s3EJWKTVdlSr5A_bNXgh02X8,4740
|
73
81
|
plain/runtime/__init__.py,sha256=o2RVETiL8U0lMFBpbtfnxflhw_4MFllMV6CEpX3RqZs,1965
|
74
|
-
plain/runtime/global_settings.py,sha256=
|
82
|
+
plain/runtime/global_settings.py,sha256=gg9XhMJmzbQqfxzst5JaI0hDIzPvTwX5M0AonJk2ISY,5579
|
75
83
|
plain/runtime/user_settings.py,sha256=uRHHVfzUvHon91_fOKj7K2WaBYwJ1gCPLfeXqKj5CTs,10902
|
76
84
|
plain/signals/README.md,sha256=FInfJXdVQkb7u93PvD8XgPbz_f6m0l2xIu_4PyttV1E,234
|
77
85
|
plain/signals/__init__.py,sha256=eAs0kLqptuP6I31dWXeAqRNji3svplpAV4Ez6ktjwXM,131
|
@@ -88,7 +96,7 @@ plain/templates/jinja/filters.py,sha256=3KJKKbxcv9dLzUDWPcaa88k3NU2m1GG3iMIgFhzX
|
|
88
96
|
plain/templates/jinja/globals.py,sha256=VMpuMZvwWOmb5MbzKK-ox-QEX_WSsXFxq0mm8biJgaU,558
|
89
97
|
plain/test/README.md,sha256=fv4YzziU2QxgcNHSgv7aDUO45sDOofVuCNrV1NPbWzo,1106
|
90
98
|
plain/test/__init__.py,sha256=MhNHtp7MYBl9kq-pMRGY11kJ6kU1I6vOkjNkit1TYRg,94
|
91
|
-
plain/test/client.py,sha256=
|
99
|
+
plain/test/client.py,sha256=lqzOf8EJo_u54dW_oiPy0m5mW-Nt3-CWyrBh9_MJnms,26930
|
92
100
|
plain/test/encoding.py,sha256=YJBOIE-BQRA5yl4zHnQy-9l67mJDTFmfy1DQXK0Wk-Q,3199
|
93
101
|
plain/test/exceptions.py,sha256=b-GHicg87Gh73W3g8QGWuSHi9PrQFVsxgWvEXDLt8gQ,290
|
94
102
|
plain/urls/README.md,sha256=ijFGmrkUY9buBqO_i1GZaN3V55vl9xwEADtHOx_ZHPY,3724
|
@@ -124,18 +132,18 @@ plain/utils/text.py,sha256=42hJv06sadbWfsaAHNhqCQaP1W9qZ69trWDTS-Xva7k,9496
|
|
124
132
|
plain/utils/timesince.py,sha256=a_-ZoPK_s3Pt998CW4rWp0clZ1XyK2x04hCqak2giII,5928
|
125
133
|
plain/utils/timezone.py,sha256=6u0sE-9RVp0_OCe0Y1KiYYQoq5THWLokZFQYY8jf78g,6221
|
126
134
|
plain/utils/tree.py,sha256=wdWzmfsgc26YDF2wxhAY3yVxXTixQYqYDKE9mL3L3ZY,4383
|
127
|
-
plain/views/README.md,sha256=
|
135
|
+
plain/views/README.md,sha256=mveTtHrd2z3knSAchW2jTwfg59_bowwhAacx-3QBBHw,6003
|
128
136
|
plain/views/__init__.py,sha256=a-N1nkklVohJTtz0yD1MMaS0g66HviEjsKydNVVjvVc,392
|
129
|
-
plain/views/base.py,sha256=
|
137
|
+
plain/views/base.py,sha256=LomceHi01okLk41YfUr6cBE0VB5FNsSVODTOQ-Rmv0I,3280
|
130
138
|
plain/views/csrf.py,sha256=7q6l5xzLWhRnMY64aNj0hR6G-3pxI2yhRwG6k_5j00E,144
|
131
139
|
plain/views/errors.py,sha256=jbNCJIzowwCsEvqyJ3opMeZpPDqTyhtrbqb0VnAm2HE,1263
|
132
140
|
plain/views/exceptions.py,sha256=b4euI49ZUKS9O8AGAcFfiDpstzkRAuuj_uYQXzWNHME,138
|
133
141
|
plain/views/forms.py,sha256=5L6dYkwcZFMD3-w_QC2QDElo9hhSPrhVVFq9CB5yL9k,2692
|
134
|
-
plain/views/objects.py,sha256=
|
135
|
-
plain/views/redirect.py,sha256=
|
136
|
-
plain/views/templates.py,sha256=
|
137
|
-
plain-0.
|
138
|
-
plain-0.
|
139
|
-
plain-0.
|
140
|
-
plain-0.
|
141
|
-
plain-0.
|
142
|
+
plain/views/objects.py,sha256=giLe9-XespeKwyEd289hfApO_9Mjwz0oddB1_2-8ko8,5713
|
143
|
+
plain/views/redirect.py,sha256=vMXx8430FtyKcT0V0gyY92SkLtyULBX52KhX4eu4gEA,1985
|
144
|
+
plain/views/templates.py,sha256=kMcHKkKNvucF91SFGkaq-ugjrCwn4zJBpFV1JkwA544,2027
|
145
|
+
plain-0.36.0.dist-info/METADATA,sha256=8WWGgPUMTMgzmwIpFovdG2nz8t-0GfokN_tdHxtFHnY,3944
|
146
|
+
plain-0.36.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
147
|
+
plain-0.36.0.dist-info/entry_points.txt,sha256=1Ys2lsSeMepD1vz8RSrJopna0RQfUd951vYvCRsvl6A,45
|
148
|
+
plain-0.36.0.dist-info/licenses/LICENSE,sha256=m0D5O7QoH9l5Vz_rrX_9r-C8d9UNr_ciK6Qwac7o6yo,3175
|
149
|
+
plain-0.36.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|