plain 0.43.1__py3-none-any.whl → 0.44.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/README.md +1 -1
- plain/csrf/middleware.py +1 -1
- plain/forms/forms.py +1 -1
- plain/http/request.py +1 -1
- plain/http/response.py +12 -2
- plain/internal/files/base.py +1 -1
- plain/internal/handlers/wsgi.py +2 -4
- plain/paginator.py +1 -1
- plain/runtime/global_settings.py +0 -6
- plain/runtime/user_settings.py +8 -4
- plain/signing.py +0 -16
- plain/utils/connection.py +1 -1
- plain/utils/functional.py +0 -43
- {plain-0.43.1.dist-info → plain-0.44.0.dist-info}/METADATA +2 -2
- {plain-0.43.1.dist-info → plain-0.44.0.dist-info}/RECORD +18 -18
- {plain-0.43.1.dist-info → plain-0.44.0.dist-info}/WHEEL +0 -0
- {plain-0.43.1.dist-info → plain-0.44.0.dist-info}/entry_points.txt +0 -0
- {plain-0.43.1.dist-info → plain-0.44.0.dist-info}/licenses/LICENSE +0 -0
plain/README.md
CHANGED
@@ -31,7 +31,7 @@ The `plain` package includes everything you need to start handling web requests
|
|
31
31
|
- [plain.cache](/plain-cache/plain/cache/README.md) - A database-driven general purpose cache.
|
32
32
|
- [plain.email](/plain-email/plain/email/README.md) - Send emails with SMTP or custom backends.
|
33
33
|
- [plain.sessions](/plain-sessions/plain/sessions/README.md) - User sessions and cookies.
|
34
|
-
- [plain.worker](/plain-worker/plain/worker/README.md) -
|
34
|
+
- [plain.worker](/plain-worker/plain/worker/README.md) - Background jobs stored in the database.
|
35
35
|
- [plain.api](/plain-api/plain/api/README.md) - Build APIs with Plain views.
|
36
36
|
|
37
37
|
## Auth Packages
|
plain/csrf/middleware.py
CHANGED
@@ -8,6 +8,7 @@ against request forgeries from other sites.
|
|
8
8
|
import logging
|
9
9
|
import string
|
10
10
|
from collections import defaultdict
|
11
|
+
from functools import cached_property
|
11
12
|
from urllib.parse import urlparse
|
12
13
|
|
13
14
|
from plain.exceptions import DisallowedHost
|
@@ -16,7 +17,6 @@ from plain.logs import log_response
|
|
16
17
|
from plain.runtime import settings
|
17
18
|
from plain.utils.cache import patch_vary_headers
|
18
19
|
from plain.utils.crypto import constant_time_compare, get_random_string
|
19
|
-
from plain.utils.functional import cached_property
|
20
20
|
from plain.utils.http import is_same_domain
|
21
21
|
from plain.utils.regex_helper import _lazy_re_compile
|
22
22
|
|
plain/forms/forms.py
CHANGED
@@ -3,9 +3,9 @@ Form classes
|
|
3
3
|
"""
|
4
4
|
|
5
5
|
import copy
|
6
|
+
from functools import cached_property
|
6
7
|
|
7
8
|
from plain.exceptions import NON_FIELD_ERRORS
|
8
|
-
from plain.utils.functional import cached_property
|
9
9
|
|
10
10
|
from .exceptions import ValidationError
|
11
11
|
from .fields import Field, FileField
|
plain/http/request.py
CHANGED
@@ -2,6 +2,7 @@ import codecs
|
|
2
2
|
import copy
|
3
3
|
import json
|
4
4
|
import uuid
|
5
|
+
from functools import cached_property
|
5
6
|
from io import BytesIO
|
6
7
|
from itertools import chain
|
7
8
|
from urllib.parse import parse_qsl, quote, urlencode, urljoin, urlsplit
|
@@ -25,7 +26,6 @@ from plain.utils.datastructures import (
|
|
25
26
|
MultiValueDict,
|
26
27
|
)
|
27
28
|
from plain.utils.encoding import iri_to_uri
|
28
|
-
from plain.utils.functional import cached_property
|
29
29
|
from plain.utils.http import is_same_domain, parse_header_parameters
|
30
30
|
from plain.utils.regex_helper import _lazy_re_compile
|
31
31
|
|
plain/http/response.py
CHANGED
@@ -18,7 +18,7 @@ from plain.json import PlainJSONEncoder
|
|
18
18
|
from plain.runtime import settings
|
19
19
|
from plain.utils import timezone
|
20
20
|
from plain.utils.datastructures import CaseInsensitiveMapping
|
21
|
-
from plain.utils.encoding import iri_to_uri
|
21
|
+
from plain.utils.encoding import force_bytes, iri_to_uri
|
22
22
|
from plain.utils.http import content_disposition_header, http_date
|
23
23
|
from plain.utils.regex_helper import _lazy_re_compile
|
24
24
|
|
@@ -258,7 +258,17 @@ class ResponseBase:
|
|
258
258
|
self.cookies[key]["samesite"] = samesite
|
259
259
|
|
260
260
|
def set_signed_cookie(self, key, value, salt="", **kwargs):
|
261
|
-
|
261
|
+
"""Set a cookie signed with the SECRET_KEY."""
|
262
|
+
|
263
|
+
def _cookie_key(k):
|
264
|
+
return b"plain.http.cookies" + force_bytes(k)
|
265
|
+
|
266
|
+
signer = signing.TimestampSigner(
|
267
|
+
key=_cookie_key(settings.SECRET_KEY),
|
268
|
+
fallback_keys=map(_cookie_key, settings.SECRET_KEY_FALLBACKS),
|
269
|
+
salt=key + salt,
|
270
|
+
)
|
271
|
+
value = signer.sign(value)
|
262
272
|
return self.set_cookie(key, value, **kwargs)
|
263
273
|
|
264
274
|
def delete_cookie(self, key, path="/", domain=None, samesite=None):
|
plain/internal/files/base.py
CHANGED
plain/internal/handlers/wsgi.py
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
import uuid
|
2
|
+
from functools import cached_property
|
2
3
|
from io import IOBase
|
3
4
|
from urllib.parse import quote
|
4
5
|
|
5
6
|
from plain import signals
|
6
7
|
from plain.http import HttpRequest, QueryDict, parse_cookie
|
7
8
|
from plain.internal.handlers import base
|
8
|
-
from plain.utils.functional import cached_property
|
9
9
|
from plain.utils.regex_helper import _lazy_re_compile
|
10
10
|
|
11
11
|
_slashes_re = _lazy_re_compile(rb"/+")
|
@@ -125,15 +125,13 @@ class WSGIRequest(HttpRequest):
|
|
125
125
|
|
126
126
|
|
127
127
|
class WSGIHandler(base.BaseHandler):
|
128
|
-
request_class = WSGIRequest
|
129
|
-
|
130
128
|
def __init__(self, *args, **kwargs):
|
131
129
|
super().__init__(*args, **kwargs)
|
132
130
|
self.load_middleware()
|
133
131
|
|
134
132
|
def __call__(self, environ, start_response):
|
135
133
|
signals.request_started.send(sender=self.__class__, environ=environ)
|
136
|
-
request =
|
134
|
+
request = WSGIRequest(environ)
|
137
135
|
response = self.get_response(request)
|
138
136
|
|
139
137
|
response._handler_class = self.__class__
|
plain/paginator.py
CHANGED
plain/runtime/global_settings.py
CHANGED
@@ -109,12 +109,6 @@ HTTP_ERROR_VIEWS: dict[int] = {}
|
|
109
109
|
# phase the middleware will be applied in reverse order.
|
110
110
|
MIDDLEWARE: list[str] = []
|
111
111
|
|
112
|
-
###########
|
113
|
-
# SIGNING #
|
114
|
-
###########
|
115
|
-
|
116
|
-
COOKIE_SIGNING_BACKEND = "plain.signing.TimestampSigner"
|
117
|
-
|
118
112
|
########
|
119
113
|
# CSRF #
|
120
114
|
########
|
plain/runtime/user_settings.py
CHANGED
@@ -121,7 +121,9 @@ class Settings:
|
|
121
121
|
if setting in self._settings:
|
122
122
|
setting_def = self._settings[setting]
|
123
123
|
try:
|
124
|
-
parsed_value = _parse_env_value(
|
124
|
+
parsed_value = _parse_env_value(
|
125
|
+
value, setting_def.annotation, setting
|
126
|
+
)
|
125
127
|
setting_def.set_value(parsed_value, "env")
|
126
128
|
except ImproperlyConfigured as e:
|
127
129
|
self._errors.append(str(e))
|
@@ -211,9 +213,11 @@ class Settings:
|
|
211
213
|
return f'<Settings "{self._settings_module}">'
|
212
214
|
|
213
215
|
|
214
|
-
def _parse_env_value(value, annotation):
|
216
|
+
def _parse_env_value(value, annotation, setting_name):
|
215
217
|
if not annotation:
|
216
|
-
raise ImproperlyConfigured(
|
218
|
+
raise ImproperlyConfigured(
|
219
|
+
f"{setting_name}: Type hint required to set from environment."
|
220
|
+
)
|
217
221
|
|
218
222
|
if annotation is bool:
|
219
223
|
# Special case for bools
|
@@ -226,7 +230,7 @@ def _parse_env_value(value, annotation):
|
|
226
230
|
return json.loads(value)
|
227
231
|
except json.JSONDecodeError as e:
|
228
232
|
raise ImproperlyConfigured(
|
229
|
-
f"Invalid JSON value for setting: {e.msg}"
|
233
|
+
f"Invalid JSON value for setting '{setting_name}': {e.msg}"
|
230
234
|
) from e
|
231
235
|
|
232
236
|
|
plain/signing.py
CHANGED
@@ -41,8 +41,6 @@ import zlib
|
|
41
41
|
|
42
42
|
from plain.runtime import settings
|
43
43
|
from plain.utils.crypto import constant_time_compare, salted_hmac
|
44
|
-
from plain.utils.encoding import force_bytes
|
45
|
-
from plain.utils.module_loading import import_string
|
46
44
|
from plain.utils.regex_helper import _lazy_re_compile
|
47
45
|
|
48
46
|
_SEP_UNSAFE = _lazy_re_compile(r"^[A-z0-9-_=]*$")
|
@@ -101,20 +99,6 @@ def base64_hmac(salt, value, key, algorithm="sha1"):
|
|
101
99
|
).decode()
|
102
100
|
|
103
101
|
|
104
|
-
def _cookie_signer_key(key):
|
105
|
-
# SECRET_KEYS items may be str or bytes.
|
106
|
-
return b"plain.http.cookies" + force_bytes(key)
|
107
|
-
|
108
|
-
|
109
|
-
def get_cookie_signer(salt="plain.signing.get_cookie_signer"):
|
110
|
-
Signer = import_string(settings.COOKIE_SIGNING_BACKEND)
|
111
|
-
return Signer(
|
112
|
-
key=_cookie_signer_key(settings.SECRET_KEY),
|
113
|
-
fallback_keys=map(_cookie_signer_key, settings.SECRET_KEY_FALLBACKS),
|
114
|
-
salt=salt,
|
115
|
-
)
|
116
|
-
|
117
|
-
|
118
102
|
class JSONSerializer:
|
119
103
|
"""
|
120
104
|
Simple wrapper around json to be used in signing.dumps and
|
plain/utils/connection.py
CHANGED
plain/utils/functional.py
CHANGED
@@ -4,49 +4,6 @@ import operator
|
|
4
4
|
from functools import total_ordering, wraps
|
5
5
|
|
6
6
|
|
7
|
-
class cached_property:
|
8
|
-
"""
|
9
|
-
Decorator that converts a method with a single self argument into a
|
10
|
-
property cached on the instance.
|
11
|
-
|
12
|
-
A cached property can be made out of an existing method:
|
13
|
-
(e.g. ``url = cached_property(get_absolute_url)``).
|
14
|
-
"""
|
15
|
-
|
16
|
-
name = None
|
17
|
-
|
18
|
-
@staticmethod
|
19
|
-
def func(instance):
|
20
|
-
raise TypeError(
|
21
|
-
"Cannot use cached_property instance without calling __set_name__() on it."
|
22
|
-
)
|
23
|
-
|
24
|
-
def __init__(self, func):
|
25
|
-
self.real_func = func
|
26
|
-
self.__doc__ = getattr(func, "__doc__")
|
27
|
-
|
28
|
-
def __set_name__(self, owner, name):
|
29
|
-
if self.name is None:
|
30
|
-
self.name = name
|
31
|
-
self.func = self.real_func
|
32
|
-
elif name != self.name:
|
33
|
-
raise TypeError(
|
34
|
-
"Cannot assign the same cached_property to two different names "
|
35
|
-
f"({self.name!r} and {name!r})."
|
36
|
-
)
|
37
|
-
|
38
|
-
def __get__(self, instance, cls=None):
|
39
|
-
"""
|
40
|
-
Call the function and put the return value in instance.__dict__ so that
|
41
|
-
subsequent attribute access on the instance returns the cached value
|
42
|
-
instead of calling cached_property.__get__().
|
43
|
-
"""
|
44
|
-
if instance is None:
|
45
|
-
return self
|
46
|
-
res = instance.__dict__[self.name] = self.func(instance)
|
47
|
-
return res
|
48
|
-
|
49
|
-
|
50
7
|
class classproperty:
|
51
8
|
"""
|
52
9
|
Decorator that converts a method with a single cls argument into a property
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: plain
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.44.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
|
@@ -42,7 +42,7 @@ The `plain` package includes everything you need to start handling web requests
|
|
42
42
|
- [plain.cache](/plain-cache/plain/cache/README.md) - A database-driven general purpose cache.
|
43
43
|
- [plain.email](/plain-email/plain/email/README.md) - Send emails with SMTP or custom backends.
|
44
44
|
- [plain.sessions](/plain-sessions/plain/sessions/README.md) - User sessions and cookies.
|
45
|
-
- [plain.worker](/plain-worker/plain/worker/README.md) -
|
45
|
+
- [plain.worker](/plain-worker/plain/worker/README.md) - Background jobs stored in the database.
|
46
46
|
- [plain.api](/plain-api/plain/api/README.md) - Build APIs with Plain views.
|
47
47
|
|
48
48
|
## Auth Packages
|
@@ -1,10 +1,10 @@
|
|
1
|
-
plain/README.md,sha256=
|
1
|
+
plain/README.md,sha256=gik6DBZcJAITcm4WRq_L53AxkjY45eQLafyTCSf0CKE,3986
|
2
2
|
plain/__main__.py,sha256=GK39854Lc_LO_JP8DzY9Y2MIQ4cQEl7SXFJy244-lC8,110
|
3
3
|
plain/debug.py,sha256=abPkJY4aSbBYGEYSZST_ZY3ohXPGDdz9uWQBYRqfd3M,730
|
4
4
|
plain/exceptions.py,sha256=Z9cbPE5im_Y-bjVq8cqC85gBoqOr80rLFG5wTKixrwE,5894
|
5
5
|
plain/json.py,sha256=McJdsbMT1sYwkGRG--f2NSZz0hVXPMix9x3nKaaak2o,1262
|
6
|
-
plain/paginator.py,sha256
|
7
|
-
plain/signing.py,sha256=
|
6
|
+
plain/paginator.py,sha256=iXiOyt2r_YwNrkqCRlaU7V-M_BKaaQ8XZElUBVa6yeU,5844
|
7
|
+
plain/signing.py,sha256=r2KvCOxkrSWCULFxYa9BHYx3L3a2oLq8RDnq_92inTw,8207
|
8
8
|
plain/validators.py,sha256=TePzFHzwR4JXUAZ_Y2vC6mkKgVxHX3QBXI6Oex0rV8c,19236
|
9
9
|
plain/wsgi.py,sha256=R6k5FiAElvGDApEbMPTT0MPqSD7n2e2Az5chQqJZU0I,236
|
10
10
|
plain/assets/README.md,sha256=wgsmBK5vAHgFMZ010q7LTrgLq5BTfuPuuug5HLZ9GNw,3774
|
@@ -34,23 +34,23 @@ plain/cli/startup.py,sha256=wLaFuyUb4ewWhtehBCGicrRCXIIGCRbeCT3ce9hUv-A,1022
|
|
34
34
|
plain/cli/urls.py,sha256=CS9NFpwZBWveAR8F3YsoUNySDEK_PwF73oSgLDfkOdI,3776
|
35
35
|
plain/cli/utils.py,sha256=VwlIh0z7XxzVV8I3qM2kZo07fkJFPoeeVZa1ODG616k,258
|
36
36
|
plain/csrf/README.md,sha256=nxCpPk1HF5eAM-7paxg9D-9RVCU9jXsSPAVHkJvA_DU,717
|
37
|
-
plain/csrf/middleware.py,sha256=
|
37
|
+
plain/csrf/middleware.py,sha256=U3B9R7ciO_UAf7O3jdNtVu6QZ_3Yrm8isRdnW6bVKX4,17401
|
38
38
|
plain/csrf/views.py,sha256=HwQqfI6KPelHP9gSXhjfZaTLQic71PKsoZ6DPhr1rKI,572
|
39
39
|
plain/forms/README.md,sha256=TawBdy1jP0-8HUsfUzd7vvgkwl3EJGejDxFhWR8F-80,2242
|
40
40
|
plain/forms/__init__.py,sha256=UxqPwB8CiYPCQdHmUc59jadqaXqDmXBH8y4bt9vTPms,226
|
41
41
|
plain/forms/boundfield.py,sha256=LhydhCVR0okrli0-QBMjGjAJ8-06gTCXVEaBZhBouQk,1741
|
42
42
|
plain/forms/exceptions.py,sha256=NYk1wjYDkk-lA_XMJQDItOebQcL_m_r2eNRc2mkLQkg,315
|
43
43
|
plain/forms/fields.py,sha256=C71ed7m8VBnsgS-eIC6Xsmz7ruNSkdGa1BuSo7V3QKc,34574
|
44
|
-
plain/forms/forms.py,sha256=
|
44
|
+
plain/forms/forms.py,sha256=hF7Dl8rEaiBTZhFQyfbh1Zf54BSEka8RYpBiGqkTa8I,10441
|
45
45
|
plain/http/README.md,sha256=F9wbahgSU3jIDEG14gJjdPJRem4weUNvwnwhb7o3cu0,722
|
46
46
|
plain/http/__init__.py,sha256=DIsDRbBsCGa4qZgq-fUuQS0kkxfbTU_3KpIM9VvH04w,1067
|
47
47
|
plain/http/cookie.py,sha256=11FnSG3Plo6T3jZDbPoCw7SKh9ExdBio3pTmIO03URg,597
|
48
48
|
plain/http/multipartparser.py,sha256=Z1dFJNAd8N5RHUuF67jh1jBfZOFepORsre_3ee6CgOQ,27266
|
49
|
-
plain/http/request.py,sha256=
|
50
|
-
plain/http/response.py,sha256=
|
49
|
+
plain/http/request.py,sha256=DbnC_E-PeiLM9pVJdcO869BtAU2gniLflMnPAOrrKU8,25618
|
50
|
+
plain/http/response.py,sha256=WvVxQgQMq9X8YRBa9_neowfP3mx3TzN90SShSulfFQo,23970
|
51
51
|
plain/internal/__init__.py,sha256=fVBaYLCXEQc-7riHMSlw3vMTTuF7-0Bj2I8aGzv0o0w,171
|
52
52
|
plain/internal/files/__init__.py,sha256=VctFgox4Q1AWF3klPaoCC5GIw5KeLafYjY5JmN8mAVw,63
|
53
|
-
plain/internal/files/base.py,sha256
|
53
|
+
plain/internal/files/base.py,sha256=2z19tik2_xgXlI6nfVZ4woSF9WB0RSUzsvOfi1Bz8Wg,4113
|
54
54
|
plain/internal/files/locks.py,sha256=z03q7IZD4tPMK3s1HKF3w_uetkFj6w6FTheLUxZsfB0,3616
|
55
55
|
plain/internal/files/move.py,sha256=jfdD29QhamxZjXRgqmZS4dJoJ4sK6M7QK1Km-69jWeo,3238
|
56
56
|
plain/internal/files/temp.py,sha256=UJJnCI8dqPIC8XXHU3-jG2-0svbkrgGlBs4yhciLm4c,2506
|
@@ -60,7 +60,7 @@ plain/internal/files/utils.py,sha256=xN4HTJXDRdcoNyrL1dFd528MBwodRlHZM8DGTD_oBIg
|
|
60
60
|
plain/internal/handlers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
61
61
|
plain/internal/handlers/base.py,sha256=6K8wd5DojOYA-UEQTd1jxdDggm5ThHXQahVcuJqd2qo,4169
|
62
62
|
plain/internal/handlers/exception.py,sha256=vfha_6-fz6S6VYCP1PMBfue2Gw-_th6jqaTE372fGlw,4809
|
63
|
-
plain/internal/handlers/wsgi.py,sha256=
|
63
|
+
plain/internal/handlers/wsgi.py,sha256=dgPT29t_F9llB-c5RYU3SHxGuZNaZ83xRjOfuOmtOl8,8209
|
64
64
|
plain/internal/middleware/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
65
65
|
plain/internal/middleware/headers.py,sha256=ENIW1Gwat54hv-ejgp2R8QTZm-PlaI7k44WU01YQrNk,964
|
66
66
|
plain/internal/middleware/https.py,sha256=XpuQK8HicYX1jNanQHqNgyQ9rqe4NLUOZO3ZzKdsP8k,1203
|
@@ -83,8 +83,8 @@ plain/preflight/security.py,sha256=oxUZBp2M0bpBfUoLYepIxoex2Y90nyjlrL8XU8UTHYY,2
|
|
83
83
|
plain/preflight/urls.py,sha256=cQ-WnFa_5oztpKdtwhuIGb7pXEml__bHsjs1SWO2YNI,1468
|
84
84
|
plain/runtime/README.md,sha256=S_FIOmSq8LkVQHh9Xm6s3EJWKTVdlSr5A_bNXgh02X8,4740
|
85
85
|
plain/runtime/__init__.py,sha256=0Q7k0V-8OfmTaKC0paNvV4Lx92L1_J7xoEWQH9aO5y4,2005
|
86
|
-
plain/runtime/global_settings.py,sha256=
|
87
|
-
plain/runtime/user_settings.py,sha256=
|
86
|
+
plain/runtime/global_settings.py,sha256=MpJ6vtBMO2EYALaKXrtgcGoxLh9Y549zwwErC5D5K7I,5343
|
87
|
+
plain/runtime/user_settings.py,sha256=OzMiEkE6ZQ50nxd1WIqirXPiNuMAQULklYHEzgzLWgA,11027
|
88
88
|
plain/signals/README.md,sha256=FInfJXdVQkb7u93PvD8XgPbz_f6m0l2xIu_4PyttV1E,234
|
89
89
|
plain/signals/__init__.py,sha256=eAs0kLqptuP6I31dWXeAqRNji3svplpAV4Ez6ktjwXM,131
|
90
90
|
plain/signals/dispatch/__init__.py,sha256=FzEygqV9HsM6gopio7O2Oh_X230nA4d5Q9s0sUjMq0E,292
|
@@ -114,7 +114,7 @@ plain/urls/utils.py,sha256=lKxTX_A3XJpIH7FjlNYju108stY6-8Sw2uVdiSsxOKQ,1249
|
|
114
114
|
plain/utils/README.md,sha256=hRRkcg4CxMX-zz8d4Bn6V2uJr_VKgTLurc1jY7QlEx8,198
|
115
115
|
plain/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
116
116
|
plain/utils/cache.py,sha256=iuvOTIfI1s857iVOAPNLK5lkzlrl0fIiBYaiUXWQu40,5303
|
117
|
-
plain/utils/connection.py,sha256=
|
117
|
+
plain/utils/connection.py,sha256=KF57CXt4tVO0EXMRwvIQX0eSruvpNQwGkK4_YGT9nXo,2488
|
118
118
|
plain/utils/crypto.py,sha256=zFDydnaqNMGYFHUc-CAn8f93685a17BhGusAcITH1lI,2662
|
119
119
|
plain/utils/datastructures.py,sha256=g4UYTbxIb_n8F9JWMP4dHPwUz71591fHreGATPO4qEc,10240
|
120
120
|
plain/utils/dateparse.py,sha256=u9_tF85YteXSjW9KQzNg_pcCEFDZS3EGorCddcWU0vE,5351
|
@@ -122,7 +122,7 @@ plain/utils/deconstruct.py,sha256=7NwEFIDCiadAArUBFmiErzDgfIgDWeKqqQFDXwSgQoQ,18
|
|
122
122
|
plain/utils/decorators.py,sha256=mLHOo2jLdvYRo2z8lkeVn2vQErlj7xC6XoLwZBYf_z8,358
|
123
123
|
plain/utils/duration.py,sha256=l0Gc41-DeyyAmpdy2XG-YO5UKxMf1NDpWIlQuD5hAn0,1162
|
124
124
|
plain/utils/encoding.py,sha256=T0Shb2xRAR3NPwwoqhpUOB55gDprWzqu72aRiiulv9Y,4251
|
125
|
-
plain/utils/functional.py,sha256=
|
125
|
+
plain/utils/functional.py,sha256=eJksrhVdkC8HKF56qtVyTOsOnkZB2jMUnXSTGzjJMF4,13331
|
126
126
|
plain/utils/hashable.py,sha256=uLWobCCh7VcEPJ7xzVGPgigNVuTazYJbyzRzHTCI_wo,739
|
127
127
|
plain/utils/html.py,sha256=SR8oNrungB5gxJaHbvAaCw_bAiqLQOk09fj-iIXY0i0,3679
|
128
128
|
plain/utils/http.py,sha256=VOOnwRXnDp5PL_qEmkInLTm10fF58vlhVjeSTdzV2cQ,6031
|
@@ -146,8 +146,8 @@ plain/views/forms.py,sha256=ESZOXuo6IeYixp1RZvPb94KplkowRiwO2eGJCM6zJI0,2400
|
|
146
146
|
plain/views/objects.py,sha256=GGbcfg_9fPZ-PiaBwIHG2e__8GfWDR7JQtQ15wTyiHg,5970
|
147
147
|
plain/views/redirect.py,sha256=daq2cQIkdDF78bt43sjuZxRAyJm_t_SKw6tyPmiXPIc,1985
|
148
148
|
plain/views/templates.py,sha256=SU1fO9gVMp-gEQHYeFplxvmgeMyrLgT8MJ12WNVmQC8,2085
|
149
|
-
plain-0.
|
150
|
-
plain-0.
|
151
|
-
plain-0.
|
152
|
-
plain-0.
|
153
|
-
plain-0.
|
149
|
+
plain-0.44.0.dist-info/METADATA,sha256=U2-CD6dtM5QQobziqQQmvdLz2EN1XhxghI587wYQSq0,4297
|
150
|
+
plain-0.44.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
151
|
+
plain-0.44.0.dist-info/entry_points.txt,sha256=1Ys2lsSeMepD1vz8RSrJopna0RQfUd951vYvCRsvl6A,45
|
152
|
+
plain-0.44.0.dist-info/licenses/LICENSE,sha256=m0D5O7QoH9l5Vz_rrX_9r-C8d9UNr_ciK6Qwac7o6yo,3175
|
153
|
+
plain-0.44.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|