plain 0.21.5__py3-none-any.whl → 0.22.1__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/urls.py +9 -8
- plain/assets/views.py +4 -4
- plain/cli/cli.py +90 -7
- plain/http/request.py +1 -2
- plain/internal/handlers/base.py +9 -23
- plain/internal/handlers/exception.py +2 -0
- plain/internal/middleware/slash.py +15 -7
- plain/packages/registry.py +3 -77
- plain/preflight/urls.py +2 -2
- plain/runtime/global_settings.py +1 -1
- plain/templates/jinja/globals.py +2 -8
- plain/test/client.py +10 -10
- plain/urls/__init__.py +8 -19
- plain/urls/patterns.py +271 -0
- plain/urls/resolvers.py +51 -361
- plain/urls/routers.py +112 -0
- plain/urls/{base.py → utils.py} +5 -61
- plain/utils/functional.py +1 -2
- plain/views/redirect.py +1 -1
- plain/views/templates.py +1 -1
- {plain-0.21.5.dist-info → plain-0.22.1.dist-info}/METADATA +1 -1
- {plain-0.21.5.dist-info → plain-0.22.1.dist-info}/RECORD +25 -25
- plain/urls/conf.py +0 -95
- plain/utils/deprecation.py +0 -6
- {plain-0.21.5.dist-info → plain-0.22.1.dist-info}/WHEEL +0 -0
- {plain-0.21.5.dist-info → plain-0.22.1.dist-info}/entry_points.txt +0 -0
- {plain-0.21.5.dist-info → plain-0.22.1.dist-info}/licenses/LICENSE +0 -0
plain/urls/routers.py
ADDED
@@ -0,0 +1,112 @@
|
|
1
|
+
import re
|
2
|
+
from abc import ABC
|
3
|
+
from types import ModuleType
|
4
|
+
from typing import TYPE_CHECKING
|
5
|
+
|
6
|
+
from plain.exceptions import ImproperlyConfigured
|
7
|
+
|
8
|
+
from .patterns import RegexPattern, RoutePattern, URLPattern
|
9
|
+
from .resolvers import (
|
10
|
+
URLResolver,
|
11
|
+
)
|
12
|
+
|
13
|
+
if TYPE_CHECKING:
|
14
|
+
from plain.views import View
|
15
|
+
|
16
|
+
|
17
|
+
class RouterBase(ABC):
|
18
|
+
namespace: str = ""
|
19
|
+
urls: list # Required
|
20
|
+
|
21
|
+
|
22
|
+
class RoutersRegistry:
|
23
|
+
"""Keep track of all the Routers that are explicitly registered in packages."""
|
24
|
+
|
25
|
+
def __init__(self):
|
26
|
+
self._routers = {}
|
27
|
+
|
28
|
+
def register_router(self, router_class):
|
29
|
+
router_module_name = router_class.__module__
|
30
|
+
self._routers[router_module_name] = router_class
|
31
|
+
return router_class
|
32
|
+
|
33
|
+
def get_module_router(self, module):
|
34
|
+
if isinstance(module, str):
|
35
|
+
module_name = module
|
36
|
+
else:
|
37
|
+
module_name = module.__name__
|
38
|
+
|
39
|
+
try:
|
40
|
+
return self._routers[module_name]
|
41
|
+
except KeyError as e:
|
42
|
+
registered_routers = ", ".join(self._routers.keys()) or "None"
|
43
|
+
raise ImproperlyConfigured(
|
44
|
+
f"Router {module_name} is not registered with the resolver. Use @register_router on the Router class in urls.py.\n\nRegistered routers: {registered_routers}"
|
45
|
+
) from e
|
46
|
+
|
47
|
+
|
48
|
+
def include(
|
49
|
+
route: str | re.Pattern, module_or_urls: list | tuple | str | ModuleType
|
50
|
+
) -> URLResolver:
|
51
|
+
"""
|
52
|
+
Include URLs from another module or a nested list of URL patterns.
|
53
|
+
"""
|
54
|
+
if isinstance(route, str):
|
55
|
+
pattern = RoutePattern(route, is_endpoint=False)
|
56
|
+
elif isinstance(route, re.Pattern):
|
57
|
+
pattern = RegexPattern(route.pattern, is_endpoint=False)
|
58
|
+
else:
|
59
|
+
raise TypeError("include() route must be a string or regex")
|
60
|
+
|
61
|
+
if isinstance(module_or_urls, list | tuple):
|
62
|
+
# We were given an explicit list of sub-patterns,
|
63
|
+
# so we generate a router for it
|
64
|
+
class _IncludeRouter(RouterBase):
|
65
|
+
urls = module_or_urls
|
66
|
+
|
67
|
+
return URLResolver(pattern=pattern, router_class=_IncludeRouter)
|
68
|
+
else:
|
69
|
+
# We were given a module, so we need to look up the router for that module
|
70
|
+
module = module_or_urls
|
71
|
+
router_class = routers_registry.get_module_router(module)
|
72
|
+
|
73
|
+
return URLResolver(
|
74
|
+
pattern=pattern,
|
75
|
+
router_class=router_class,
|
76
|
+
)
|
77
|
+
|
78
|
+
|
79
|
+
def path(route: str | re.Pattern, view: "View", *, name: str = "") -> URLPattern:
|
80
|
+
"""
|
81
|
+
Standard URL with a view.
|
82
|
+
"""
|
83
|
+
from plain.views import View
|
84
|
+
|
85
|
+
if isinstance(route, str):
|
86
|
+
pattern = RoutePattern(route, name=name, is_endpoint=True)
|
87
|
+
elif isinstance(route, re.Pattern):
|
88
|
+
pattern = RegexPattern(route.pattern, name=name, is_endpoint=True)
|
89
|
+
else:
|
90
|
+
raise TypeError("path() route must be a string or regex")
|
91
|
+
|
92
|
+
# You can't pass a View() instance to path()
|
93
|
+
if isinstance(view, View):
|
94
|
+
view_cls_name = view.__class__.__name__
|
95
|
+
raise TypeError(
|
96
|
+
f"view must be a callable, pass {view_cls_name} or {view_cls_name}.as_view(*args, **kwargs), not "
|
97
|
+
f"{view_cls_name}()."
|
98
|
+
)
|
99
|
+
|
100
|
+
# You typically pass a View class and we call as_view() for you
|
101
|
+
if issubclass(view, View):
|
102
|
+
return URLPattern(pattern=pattern, view=view.as_view(), name=name)
|
103
|
+
|
104
|
+
# If you called View.as_view() yourself (or technically any callable)
|
105
|
+
if callable(view):
|
106
|
+
return URLPattern(pattern=pattern, view=view, name=name)
|
107
|
+
|
108
|
+
raise TypeError("view must be a View class or View.as_view()")
|
109
|
+
|
110
|
+
|
111
|
+
routers_registry = RoutersRegistry()
|
112
|
+
register_router = routers_registry.register_router
|
plain/urls/{base.py → utils.py}
RENAMED
@@ -1,37 +1,18 @@
|
|
1
|
-
from threading import local
|
2
|
-
|
3
1
|
from plain.utils.functional import lazy
|
4
2
|
|
5
|
-
from .exceptions import NoReverseMatch
|
6
|
-
from .resolvers import
|
7
|
-
|
8
|
-
# Overridden URLconfs for each thread are stored here.
|
9
|
-
_urlconfs = local()
|
10
|
-
|
11
|
-
|
12
|
-
def resolve(path, urlconf=None):
|
13
|
-
if urlconf is None:
|
14
|
-
urlconf = get_urlconf()
|
15
|
-
return get_resolver(urlconf).resolve(path)
|
3
|
+
from .exceptions import NoReverseMatch
|
4
|
+
from .resolvers import get_ns_resolver, get_resolver
|
16
5
|
|
17
6
|
|
18
|
-
def reverse(viewname,
|
19
|
-
|
20
|
-
urlconf = get_urlconf()
|
21
|
-
resolver = get_resolver(urlconf)
|
22
|
-
args = args or []
|
23
|
-
kwargs = kwargs or {}
|
7
|
+
def reverse(viewname, *args, **kwargs):
|
8
|
+
resolver = get_resolver()
|
24
9
|
|
25
10
|
if not isinstance(viewname, str):
|
26
11
|
view = viewname
|
27
12
|
else:
|
28
13
|
*path, view = viewname.split(":")
|
29
14
|
|
30
|
-
|
31
|
-
current_path = using_namespace.split(":")
|
32
|
-
current_path.reverse()
|
33
|
-
else:
|
34
|
-
current_path = None
|
15
|
+
current_path = None
|
35
16
|
|
36
17
|
resolved_path = []
|
37
18
|
ns_pattern = ""
|
@@ -79,40 +60,3 @@ def reverse(viewname, urlconf=None, args=None, kwargs=None, using_namespace=None
|
|
79
60
|
|
80
61
|
|
81
62
|
reverse_lazy = lazy(reverse, str)
|
82
|
-
|
83
|
-
|
84
|
-
def clear_url_caches():
|
85
|
-
_get_cached_resolver.cache_clear()
|
86
|
-
get_ns_resolver.cache_clear()
|
87
|
-
|
88
|
-
|
89
|
-
def set_urlconf(urlconf_name):
|
90
|
-
"""
|
91
|
-
Set the URLconf for the current thread (overriding the default one in
|
92
|
-
settings). If urlconf_name is None, revert back to the default.
|
93
|
-
"""
|
94
|
-
if urlconf_name:
|
95
|
-
_urlconfs.value = urlconf_name
|
96
|
-
else:
|
97
|
-
if hasattr(_urlconfs, "value"):
|
98
|
-
del _urlconfs.value
|
99
|
-
|
100
|
-
|
101
|
-
def get_urlconf(default=None):
|
102
|
-
"""
|
103
|
-
Return the root URLconf to use for the current thread if it has been
|
104
|
-
changed from the default one.
|
105
|
-
"""
|
106
|
-
return getattr(_urlconfs, "value", default)
|
107
|
-
|
108
|
-
|
109
|
-
def is_valid_path(path, urlconf=None):
|
110
|
-
"""
|
111
|
-
Return the ResolverMatch if the given path resolves against the default URL
|
112
|
-
resolver, False otherwise. This is a convenience method to make working
|
113
|
-
with "is this a match?" cases easier, avoiding try...except blocks.
|
114
|
-
"""
|
115
|
-
try:
|
116
|
-
return resolve(path, urlconf)
|
117
|
-
except Resolver404:
|
118
|
-
return False
|
plain/utils/functional.py
CHANGED
@@ -18,8 +18,7 @@ class cached_property:
|
|
18
18
|
@staticmethod
|
19
19
|
def func(instance):
|
20
20
|
raise TypeError(
|
21
|
-
"Cannot use cached_property instance without calling "
|
22
|
-
"__set_name__() on it."
|
21
|
+
"Cannot use cached_property instance without calling __set_name__() on it."
|
23
22
|
)
|
24
23
|
|
25
24
|
def __init__(self, func):
|
plain/views/redirect.py
CHANGED
@@ -29,7 +29,7 @@ class RedirectView(View):
|
|
29
29
|
if self.url:
|
30
30
|
url = self.url % self.url_kwargs
|
31
31
|
elif self.pattern_name:
|
32
|
-
url = reverse(self.pattern_name,
|
32
|
+
url = reverse(self.pattern_name, *self.url_args, **self.url_kwargs)
|
33
33
|
else:
|
34
34
|
return None
|
35
35
|
|
plain/views/templates.py
CHANGED
@@ -12,11 +12,11 @@ plain/assets/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
12
12
|
plain/assets/compile.py,sha256=Qg-rMWykij_Jheq4THrPFWlmYv07ihHzWiNsD815HYE,3336
|
13
13
|
plain/assets/finders.py,sha256=wMa0GUi4S5SUXKcWSqEesMgU4NbXXDrC4SMJwDakwNc,1215
|
14
14
|
plain/assets/fingerprints.py,sha256=1NKAnnXVlncY5iimXztr0NL3RIjBKsNlZRIe6nmItJc,931
|
15
|
-
plain/assets/urls.py,sha256=
|
16
|
-
plain/assets/views.py,sha256=
|
15
|
+
plain/assets/urls.py,sha256=lW7VzKNzTKY11JqbszhJQ1Yy0HtljZlsHDnnkTPdLOM,992
|
16
|
+
plain/assets/views.py,sha256=z7noLzoelGw_8-MXcvGKjXs9KZ43Tivmy2TIfnZIpgw,9253
|
17
17
|
plain/cli/README.md,sha256=TvWCnNwb1rNthPzJglCRMKacN5H_RLeEjYBMe62Uz4M,2461
|
18
18
|
plain/cli/__init__.py,sha256=9ByBOIdM8DebChjNz-RH2atdz4vWe8somlwNEsbhwh4,40
|
19
|
-
plain/cli/cli.py,sha256=
|
19
|
+
plain/cli/cli.py,sha256=0iHzlXWQTLxWxqxGV4f4K9ABT7s5q5gzSqoNzj0XuKg,18383
|
20
20
|
plain/cli/formatting.py,sha256=1hZH13y1qwHcU2K2_Na388nw9uvoeQH8LrWL-O9h8Yc,2207
|
21
21
|
plain/cli/packages.py,sha256=TiLirp0ccj5K96jOfp_pS18rOnk1aQS9ckiTi27aRwE,2740
|
22
22
|
plain/cli/print.py,sha256=XraUYrgODOJquIiEv78wSCYGRBplHXtXSS9QtFG5hqY,217
|
@@ -34,7 +34,7 @@ plain/http/README.md,sha256=HjEtoAhn14OoMdgb-wK-uc8No7C4d4gZUhzseOp7Fg4,236
|
|
34
34
|
plain/http/__init__.py,sha256=DIsDRbBsCGa4qZgq-fUuQS0kkxfbTU_3KpIM9VvH04w,1067
|
35
35
|
plain/http/cookie.py,sha256=11FnSG3Plo6T3jZDbPoCw7SKh9ExdBio3pTmIO03URg,597
|
36
36
|
plain/http/multipartparser.py,sha256=k6BhpilFENQQ1cuGix6aa-jGwbhBVms2A2O01-s3_4c,27304
|
37
|
-
plain/http/request.py,sha256=
|
37
|
+
plain/http/request.py,sha256=Kp0q-1obg7ZUJBz7iuyHwPmNMnssZmoIdLp8ylxJNAo,25965
|
38
38
|
plain/http/response.py,sha256=RR2sUG-ONWKWcZyIbztjWvtFyh0cR-CoxQvnWOyN0io,23619
|
39
39
|
plain/internal/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
40
40
|
plain/internal/files/README.md,sha256=kMux-NU5qiH0o1K8IajYQT8VjrYl_jLk9LkGG_kGuSc,45
|
@@ -47,13 +47,13 @@ plain/internal/files/uploadedfile.py,sha256=JRB7T3quQjg-1y3l1ASPxywtSQZhaeMc45uF
|
|
47
47
|
plain/internal/files/uploadhandler.py,sha256=eEnd5onstypjHYtg367PnVWwCaF1kAPlLPSV7goIf_E,7198
|
48
48
|
plain/internal/files/utils.py,sha256=xN4HTJXDRdcoNyrL1dFd528MBwodRlHZM8DGTD_oBIg,2646
|
49
49
|
plain/internal/handlers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
50
|
-
plain/internal/handlers/base.py,sha256=
|
51
|
-
plain/internal/handlers/exception.py,sha256=
|
50
|
+
plain/internal/handlers/base.py,sha256=oRKni79ATI_u7sywGFExrzKvP5dpJTqIp1m521A90Ew,4169
|
51
|
+
plain/internal/handlers/exception.py,sha256=rv8shMlTJdIhTm99VacILIiu5JRcmtumg8yWuy7GYto,4592
|
52
52
|
plain/internal/handlers/wsgi.py,sha256=estA1QKHTk3ZqziWxenHsw5UO2cwPp3Zr0XjkDeM5TY,7561
|
53
53
|
plain/internal/middleware/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
54
54
|
plain/internal/middleware/headers.py,sha256=ENIW1Gwat54hv-ejgp2R8QTZm-PlaI7k44WU01YQrNk,964
|
55
55
|
plain/internal/middleware/https.py,sha256=XpuQK8HicYX1jNanQHqNgyQ9rqe4NLUOZO3ZzKdsP8k,1203
|
56
|
-
plain/internal/middleware/slash.py,sha256=
|
56
|
+
plain/internal/middleware/slash.py,sha256=FMU8b9w0NSx4eJs9Y7Ew6RAoSTbUqe2oOM68kg3wOng,2817
|
57
57
|
plain/logs/README.md,sha256=H6uVXdInYlasq0Z1WnhWnPmNwYQoZ1MSLPDQ4ZE7u4A,492
|
58
58
|
plain/logs/__init__.py,sha256=rASvo4qFBDIHfkACmGLNGa6lRGbG9PbNjW6FmBt95ys,168
|
59
59
|
plain/logs/configure.py,sha256=6mV7d1IxkDYT3VBz61qhIj0Esuy5l5QdQfsHaGCfI6w,1063
|
@@ -62,17 +62,17 @@ plain/logs/utils.py,sha256=9UzdCCQXJinGDs71Ngw297mlWkhgZStSd67ya4NOW98,1257
|
|
62
62
|
plain/packages/README.md,sha256=Vq1Nw3mmEmZ2IriQavuVi4BjcQC2nb8k7YIbnm8QjIg,799
|
63
63
|
plain/packages/__init__.py,sha256=DnHN1wwHXiXib4Y9BV__x9WrbUaTovoTIxW-tVyScTU,106
|
64
64
|
plain/packages/config.py,sha256=6j6Y9Uw4Lbye1M7LVgOhL4rAMkSSkleTzHQU9JRBW7k,11070
|
65
|
-
plain/packages/registry.py,sha256=
|
65
|
+
plain/packages/registry.py,sha256=YMYGGrMWPoj4Bg_MXDVNnnoqOAufG_IBT24DB-twAgw,14860
|
66
66
|
plain/preflight/README.md,sha256=-PKVd0RBMh4ROiMkegPS2PgvT1Kq9qqN1KfNkmUSdFc,177
|
67
67
|
plain/preflight/__init__.py,sha256=H-TNRvaddPtOGmv4RXoc1fxDV1AOb7_K3u7ECF8mV58,607
|
68
68
|
plain/preflight/files.py,sha256=wbHCNgps7o1c1zQNBd8FDCaVaqX90UwuvLgEQ_DbUpY,510
|
69
69
|
plain/preflight/messages.py,sha256=HwatjA6MRFfzFAnSOa_uAw1Pvk_CLuNfW3IYi71_1Mk,2322
|
70
70
|
plain/preflight/registry.py,sha256=7s7f_iEwURzv-Ye515P5lJWcHltd5Ca2fsX1Wpbf1wQ,2306
|
71
71
|
plain/preflight/security.py,sha256=sNpv5AHobPcaO48cOUGRNe2EjusTducjY8vyShR8EhI,2645
|
72
|
-
plain/preflight/urls.py,sha256=
|
72
|
+
plain/preflight/urls.py,sha256=q3ikavMB8ZFMzzm_JOnm1YKwSONgaHjH4Is4-4mmTKM,3001
|
73
73
|
plain/runtime/README.md,sha256=Q8VVO7JRGuYrDxzuYL6ptoilhclbecxKzpRXKgbWGkU,2061
|
74
74
|
plain/runtime/__init__.py,sha256=ZfypqlhtbWUoJ84vLW4aKgpx2HsdtdJfDZnbbZw6kLE,1510
|
75
|
-
plain/runtime/global_settings.py,sha256=
|
75
|
+
plain/runtime/global_settings.py,sha256=SfOhwzpZe2zpNqSpdx3hHgCN89xdbW9KJVR4KJfS_Gk,5498
|
76
76
|
plain/runtime/user_settings.py,sha256=r6uQ-h0QxX3gSB_toJJekEbSikXXdNSb8ykUtwGTpdY,11280
|
77
77
|
plain/signals/README.md,sha256=cd3tKEgH-xc88CUWyDxl4-qv-HBXx8VT32BXVwA5azA,230
|
78
78
|
plain/signals/__init__.py,sha256=eAs0kLqptuP6I31dWXeAqRNji3svplpAV4Ez6ktjwXM,131
|
@@ -87,17 +87,18 @@ plain/templates/jinja/__init__.py,sha256=jGjtygVB5Bwknpd3u_pBSrtUSGlFkYo6MDo0E3I
|
|
87
87
|
plain/templates/jinja/environments.py,sha256=T5e8rjVteN3-6IWCXNRsvPgMe0OVvTkX-r6_Q9gxhv8,2046
|
88
88
|
plain/templates/jinja/extensions.py,sha256=AEmmmHDbdRW8fhjYDzq9eSSNbp9WHsXenD8tPthjc0s,1351
|
89
89
|
plain/templates/jinja/filters.py,sha256=3KJKKbxcv9dLzUDWPcaa88k3NU2m1GG3iMIgFhzXrBA,860
|
90
|
-
plain/templates/jinja/globals.py,sha256=
|
90
|
+
plain/templates/jinja/globals.py,sha256=xx3sQBn0Hkqp9jM0fZDlCM5_35C23FrZL6jKEifL77k,498
|
91
91
|
plain/test/README.md,sha256=Zso3Ir7a8vQerzKB6egjROQWkpveLAbscn7VTROPAiU,37
|
92
92
|
plain/test/__init__.py,sha256=rXe88Y602NP8DBnReSyXb7dUzKoWweLuT43j-qwOUl4,138
|
93
|
-
plain/test/client.py,sha256=
|
93
|
+
plain/test/client.py,sha256=36Cir1KbrNEhza-5FTgdwxe1iZ5zaEDtESrqcnyndnY,31318
|
94
94
|
plain/urls/README.md,sha256=pWnCvgYkWN7rG7hSyBOtX4ZUP3iO7FhqM6lvwwYll6c,33
|
95
|
-
plain/urls/__init__.py,sha256=
|
96
|
-
plain/urls/base.py,sha256=Q1TzI5WvqYkN1U81fDom1q-AID4dXbszEMF6wAeTAI0,3717
|
97
|
-
plain/urls/conf.py,sha256=3R2dCr4iryMPXgUZqESZvqrhTLa5I7PzNY98SuCYYec,3491
|
95
|
+
plain/urls/__init__.py,sha256=XF-W2GqLMA4bHbDRKnpZ7tiUtJ-BhWN-yAzw4nNnHdc,590
|
98
96
|
plain/urls/converters.py,sha256=s2JZVOdzZC16lgobsI93hygcdH5L0Kj4742WEkXsVcs,1193
|
99
97
|
plain/urls/exceptions.py,sha256=q4iPh3Aa-zHbA-tw8v6WyX1J1n5WdAady2xvxFuyXB0,114
|
100
|
-
plain/urls/
|
98
|
+
plain/urls/patterns.py,sha256=bU_xfhZbKMSgRG9OJ8w_NSuYRm_9zGnqoz_WY44fhUk,9358
|
99
|
+
plain/urls/resolvers.py,sha256=T_N7hZ2VrWWpLNkMbzpNcPK8OJb4yPt6QoK_qIls4D8,15592
|
100
|
+
plain/urls/routers.py,sha256=0vwzL5udLfQDwFfE4_3lzRVq0Lsx9RcDF4rnnEiJJ1w,3613
|
101
|
+
plain/urls/utils.py,sha256=WiGq6hHI-5DLFOxCQTAZ2qm0J-UdGosLcjuxlfK6_Tg,2137
|
101
102
|
plain/utils/README.md,sha256=Bf5OG-MkOJDz_U8RGVreDfAI4M4nnPaLtk-LdinxHSc,99
|
102
103
|
plain/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
103
104
|
plain/utils/_os.py,sha256=oqfiKZRbmHwwWSZP36SIajQnFDbImbB6gcyK0idAGl4,1988
|
@@ -110,11 +111,10 @@ plain/utils/dateparse.py,sha256=u9_tF85YteXSjW9KQzNg_pcCEFDZS3EGorCddcWU0vE,5351
|
|
110
111
|
plain/utils/dates.py,sha256=hSDKz8eIb3W5QjmGiklFZZELB0inYXsfiRUy49Cx-2Q,1226
|
111
112
|
plain/utils/deconstruct.py,sha256=7NwEFIDCiadAArUBFmiErzDgfIgDWeKqqQFDXwSgQoQ,1830
|
112
113
|
plain/utils/decorators.py,sha256=mLHOo2jLdvYRo2z8lkeVn2vQErlj7xC6XoLwZBYf_z8,358
|
113
|
-
plain/utils/deprecation.py,sha256=qtj33kHEmJU7mGSrNcKidZsMo5W8MN-zrXzUq3aVVy8,131
|
114
114
|
plain/utils/duration.py,sha256=l0Gc41-DeyyAmpdy2XG-YO5UKxMf1NDpWIlQuD5hAn0,1162
|
115
115
|
plain/utils/email.py,sha256=puRTBVuz44YvpnqV3LT4nNIKqdqfY3L8zbDJIkqHk2Y,328
|
116
116
|
plain/utils/encoding.py,sha256=z8c7HxYW6wQiE4csx5Ui3WvzgbDzLGXY2aCP04_GZd4,7900
|
117
|
-
plain/utils/functional.py,sha256=
|
117
|
+
plain/utils/functional.py,sha256=Xf51mt5bB8zehR8pTRVnRfV21vJ4n1IGpcwj88SSsUA,14791
|
118
118
|
plain/utils/hashable.py,sha256=uLWobCCh7VcEPJ7xzVGPgigNVuTazYJbyzRzHTCI_wo,739
|
119
119
|
plain/utils/html.py,sha256=K8nJSiNRU54htQOfhezZAYspXaDGN3LjOE3SxmnQml8,13513
|
120
120
|
plain/utils/http.py,sha256=OmnqW_nYUaFN-pAEwjTEh9AkpfjKGmE51Ge6inNGB10,12710
|
@@ -136,10 +136,10 @@ plain/views/errors.py,sha256=Y4oGX4Z6D2COKcDEfINvXE1acE8Ad15KwNNWPs5BCfc,967
|
|
136
136
|
plain/views/exceptions.py,sha256=b4euI49ZUKS9O8AGAcFfiDpstzkRAuuj_uYQXzWNHME,138
|
137
137
|
plain/views/forms.py,sha256=RhlaUcZCkeqokY_fvv-NOS-kgZAG4XhDLOPbf9K_Zlc,2691
|
138
138
|
plain/views/objects.py,sha256=g5Lzno0Zsv0K449UpcCtxwCoO7WMRAWqKlxxV2V0_qg,8263
|
139
|
-
plain/views/redirect.py,sha256=
|
140
|
-
plain/views/templates.py,sha256=
|
141
|
-
plain-0.
|
142
|
-
plain-0.
|
143
|
-
plain-0.
|
144
|
-
plain-0.
|
145
|
-
plain-0.
|
139
|
+
plain/views/redirect.py,sha256=9zHZgKvtSkdrMX9KmsRM8hJTPmBktxhc4d8OitbuniI,1724
|
140
|
+
plain/views/templates.py,sha256=cBkFNCSXgVi8cMqQbhsqJ4M_rIQYVl8cUvq9qu4YIes,1951
|
141
|
+
plain-0.22.1.dist-info/METADATA,sha256=lbcAVRTvoSbCtA3Nlt-ShyzQV1UOhb2bk_FSDKL5pS4,319
|
142
|
+
plain-0.22.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
143
|
+
plain-0.22.1.dist-info/entry_points.txt,sha256=DHHprvufgd7xypiBiqMANYRnpJ9xPPYhYbnPGwOkWqE,40
|
144
|
+
plain-0.22.1.dist-info/licenses/LICENSE,sha256=m0D5O7QoH9l5Vz_rrX_9r-C8d9UNr_ciK6Qwac7o6yo,3175
|
145
|
+
plain-0.22.1.dist-info/RECORD,,
|
plain/urls/conf.py
DELETED
@@ -1,95 +0,0 @@
|
|
1
|
-
"""Functions for use in URLsconfs."""
|
2
|
-
|
3
|
-
from functools import partial
|
4
|
-
|
5
|
-
from plain.exceptions import ImproperlyConfigured
|
6
|
-
|
7
|
-
from .resolvers import (
|
8
|
-
RegexPattern,
|
9
|
-
RoutePattern,
|
10
|
-
URLPattern,
|
11
|
-
URLResolver,
|
12
|
-
)
|
13
|
-
|
14
|
-
|
15
|
-
def include(arg, namespace=None):
|
16
|
-
default_namespace = None
|
17
|
-
if isinstance(arg, tuple):
|
18
|
-
# Callable returning a namespace hint.
|
19
|
-
try:
|
20
|
-
urlconf_module, default_namespace = arg
|
21
|
-
except ValueError:
|
22
|
-
if namespace:
|
23
|
-
raise ImproperlyConfigured(
|
24
|
-
"Cannot override the namespace for a dynamic module that "
|
25
|
-
"provides a namespace."
|
26
|
-
)
|
27
|
-
raise ImproperlyConfigured(
|
28
|
-
"Passing a %d-tuple to include() is not supported. Pass a " # noqa: UP031
|
29
|
-
"2-tuple containing the list of patterns and default_namespace, and "
|
30
|
-
"provide the namespace argument to include() instead." % len(arg)
|
31
|
-
)
|
32
|
-
else:
|
33
|
-
# No namespace hint - use manually provided namespace.
|
34
|
-
urlconf_module = arg
|
35
|
-
|
36
|
-
patterns = getattr(urlconf_module, "urlpatterns", urlconf_module)
|
37
|
-
default_namespace = getattr(urlconf_module, "default_namespace", default_namespace)
|
38
|
-
if namespace and not default_namespace:
|
39
|
-
raise ImproperlyConfigured(
|
40
|
-
"Specifying a namespace in include() without providing an default_namespace "
|
41
|
-
"is not supported. Set the default_namespace attribute in the included "
|
42
|
-
"module, or pass a 2-tuple containing the list of patterns and "
|
43
|
-
"default_namespace instead.",
|
44
|
-
)
|
45
|
-
namespace = namespace or default_namespace
|
46
|
-
# Make sure the patterns can be iterated through (without this, some
|
47
|
-
# testcases will break).
|
48
|
-
if isinstance(patterns, list | tuple):
|
49
|
-
for url_pattern in patterns:
|
50
|
-
getattr(url_pattern, "pattern", None)
|
51
|
-
return (urlconf_module, default_namespace, namespace)
|
52
|
-
|
53
|
-
|
54
|
-
def _path(route, view, kwargs=None, name=None, Pattern=None):
|
55
|
-
from plain.views import View
|
56
|
-
|
57
|
-
if kwargs is not None and not isinstance(kwargs, dict):
|
58
|
-
raise TypeError(
|
59
|
-
f"kwargs argument must be a dict, but got {kwargs.__class__.__name__}."
|
60
|
-
)
|
61
|
-
|
62
|
-
if isinstance(view, list | tuple):
|
63
|
-
# For include(...) processing.
|
64
|
-
pattern = Pattern(route, is_endpoint=False)
|
65
|
-
urlconf_module, default_namespace, namespace = view
|
66
|
-
return URLResolver(
|
67
|
-
pattern,
|
68
|
-
urlconf_module,
|
69
|
-
kwargs,
|
70
|
-
default_namespace=default_namespace,
|
71
|
-
namespace=namespace,
|
72
|
-
)
|
73
|
-
|
74
|
-
if isinstance(view, View):
|
75
|
-
view_cls_name = view.__class__.__name__
|
76
|
-
raise TypeError(
|
77
|
-
f"view must be a callable, pass {view_cls_name} or {view_cls_name}.as_view(*args, **kwargs), not "
|
78
|
-
f"{view_cls_name}()."
|
79
|
-
)
|
80
|
-
|
81
|
-
# Automatically call view.as_view() for class-based views
|
82
|
-
if as_view := getattr(view, "as_view", None):
|
83
|
-
pattern = Pattern(route, name=name, is_endpoint=True)
|
84
|
-
return URLPattern(pattern, as_view(), kwargs, name)
|
85
|
-
|
86
|
-
# Function-based views or view_class.as_view() usage
|
87
|
-
if callable(view):
|
88
|
-
pattern = Pattern(route, name=name, is_endpoint=True)
|
89
|
-
return URLPattern(pattern, view, kwargs, name)
|
90
|
-
|
91
|
-
raise TypeError("view must be a callable or a list/tuple in the case of include().")
|
92
|
-
|
93
|
-
|
94
|
-
path = partial(_path, Pattern=RoutePattern)
|
95
|
-
re_path = partial(_path, Pattern=RegexPattern)
|
plain/utils/deprecation.py
DELETED
File without changes
|
File without changes
|
File without changes
|