plain 0.23.1__py3-none-any.whl → 0.24.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/finders.py CHANGED
@@ -1,6 +1,6 @@
1
1
  import os
2
2
 
3
- from plain.packages import packages
3
+ from plain.packages import packages_registry
4
4
  from plain.runtime import APP_PATH
5
5
 
6
6
  APP_ASSETS_DIR = APP_PATH / "assets"
@@ -33,7 +33,7 @@ def iter_assets():
33
33
 
34
34
  def iter_asset_dirs():
35
35
  # Iterate the installed package assets, in order
36
- for pkg in packages.get_package_configs():
36
+ for pkg in packages_registry.get_package_configs():
37
37
  asset_dir = os.path.join(pkg.path, "assets")
38
38
  if os.path.exists(asset_dir):
39
39
  yield asset_dir
plain/cli/cli.py CHANGED
@@ -16,7 +16,7 @@ import plain.runtime
16
16
  from plain import preflight
17
17
  from plain.assets.compile import compile_assets, get_compiled_path
18
18
  from plain.exceptions import ImproperlyConfigured
19
- from plain.packages import packages
19
+ from plain.packages import packages_registry
20
20
  from plain.utils.crypto import get_random_string
21
21
 
22
22
  from .formatting import PlainContext
@@ -161,7 +161,7 @@ def preflight_checks(package_label, deploy, fail_level, databases):
161
161
 
162
162
  if package_label:
163
163
  package_configs = [
164
- packages.get_package_config(label) for label in package_label
164
+ packages_registry.get_package_config(label) for label in package_label
165
165
  ]
166
166
  else:
167
167
  package_configs = None
plain/cli/packages.py CHANGED
@@ -4,7 +4,7 @@ from importlib.util import find_spec
4
4
 
5
5
  import click
6
6
 
7
- from plain.packages import packages
7
+ from plain.packages import packages_registry
8
8
 
9
9
 
10
10
  class InstalledPackagesGroup(click.Group):
@@ -21,7 +21,7 @@ class InstalledPackagesGroup(click.Group):
21
21
  command_names = []
22
22
 
23
23
  # Get installed packages with a cli.py module
24
- for app in packages.get_package_configs():
24
+ for app in packages_registry.get_package_configs():
25
25
  if not find_spec(f"{app.name}.{self.MODULE_NAME}"):
26
26
  continue
27
27
 
@@ -1,4 +1,4 @@
1
1
  from .config import PackageConfig
2
- from .registry import packages
2
+ from .registry import packages_registry
3
3
 
4
- __all__ = ["PackageConfig", "packages"]
4
+ __all__ = ["PackageConfig", "packages_registry"]
plain/packages/config.py CHANGED
@@ -6,7 +6,6 @@ from plain.exceptions import ImproperlyConfigured
6
6
  from plain.utils.module_loading import import_string, module_has_submodule
7
7
 
8
8
  CONFIG_MODULE_NAME = "config"
9
- MODELS_MODULE_NAME = "models"
10
9
 
11
10
 
12
11
  class PackageConfig:
@@ -24,7 +23,7 @@ class PackageConfig:
24
23
 
25
24
  # Reference to the Packages registry that holds this PackageConfig. Set by the
26
25
  # registry when it registers the PackageConfig instance.
27
- self.packages = None
26
+ self.packages_registry = None
28
27
 
29
28
  # The following attributes could be defined at the class level in a
30
29
  # subclass, hence the test-and-set pattern.
@@ -43,15 +42,6 @@ class PackageConfig:
43
42
  if not hasattr(self, "path"):
44
43
  self.path = self._path_from_module(package_module)
45
44
 
46
- # Module containing models e.g. <module 'plain.admin.models'
47
- # from 'admin/models.py'>. Set by import_models().
48
- # None if the application doesn't have a models module.
49
- self.models_module = None
50
-
51
- # Mapping of lowercase model names to model classes. Initially set to
52
- # None to prevent accidental access before import_models() runs.
53
- self.models = None
54
-
55
45
  def __repr__(self):
56
46
  return f"<{self.__class__.__name__}: {self.label}>"
57
47
 
@@ -200,53 +190,6 @@ class PackageConfig:
200
190
  # Entry is a path to an app config class.
201
191
  return package_config_class(package_name, package_module)
202
192
 
203
- def get_model(self, model_name, require_ready=True):
204
- """
205
- Return the model with the given case-insensitive model_name.
206
-
207
- Raise LookupError if no model exists with this name.
208
- """
209
- if require_ready:
210
- self.packages.check_models_ready()
211
- else:
212
- self.packages.check_packages_ready()
213
- try:
214
- return self.models[model_name.lower()]
215
- except KeyError:
216
- raise LookupError(
217
- f"Package '{self.label}' doesn't have a '{model_name}' model."
218
- )
219
-
220
- def get_models(self, include_auto_created=False, include_swapped=False):
221
- """
222
- Return an iterable of models.
223
-
224
- By default, the following models aren't included:
225
-
226
- - auto-created models for many-to-many relations without
227
- an explicit intermediate table,
228
- - models that have been swapped out.
229
-
230
- Set the corresponding keyword argument to True to include such models.
231
- Keyword arguments aren't documented; they're a private API.
232
- """
233
- self.packages.check_models_ready()
234
- for model in self.models.values():
235
- if model._meta.auto_created and not include_auto_created:
236
- continue
237
- if model._meta.swapped and not include_swapped:
238
- continue
239
- yield model
240
-
241
- def import_models(self):
242
- # Dictionary of models for this app, primarily maintained in the
243
- # 'all_models' attribute of the Packages this PackageConfig is attached to.
244
- self.models = self.packages.all_models[self.label]
245
-
246
- if module_has_submodule(self.module, MODELS_MODULE_NAME):
247
- models_module_name = f"{self.name}.{MODELS_MODULE_NAME}"
248
- self.models_module = import_module(models_module_name)
249
-
250
193
  def ready(self):
251
194
  """
252
195
  Override this method in subclasses to run code when Plain starts.
@@ -10,7 +10,7 @@ from plain.exceptions import ImproperlyConfigured, PackageRegistryNotReady
10
10
  from .config import PackageConfig
11
11
 
12
12
 
13
- class Packages:
13
+ class PackagesRegistry:
14
14
  """
15
15
  A registry that stores the configuration of installed applications.
16
16
 
@@ -21,7 +21,9 @@ class Packages:
21
21
  # installed_packages is set to None when creating the main registry
22
22
  # because it cannot be populated at that point. Other registries must
23
23
  # provide a list of installed packages and are populated immediately.
24
- if installed_packages is None and hasattr(sys.modules[__name__], "packages"):
24
+ if installed_packages is None and hasattr(
25
+ sys.modules[__name__], "packages_registry"
26
+ ):
25
27
  raise RuntimeError("You must supply an installed_packages argument.")
26
28
 
27
29
  # Mapping of app labels => model names => model classes.
@@ -90,7 +92,7 @@ class Packages:
90
92
  )
91
93
 
92
94
  self.package_configs[package_config.label] = package_config
93
- package_config.packages = self
95
+ package_config.packages_registry = self
94
96
 
95
97
  # Check for duplicate app names.
96
98
  counts = Counter(
@@ -106,18 +108,14 @@ class Packages:
106
108
 
107
109
  self.packages_ready = True
108
110
 
109
- # Phase 2: import models modules.
110
- for package_config in self.package_configs.values():
111
- package_config.import_models()
111
+ # Phase 3: run ready() methods of app configs.
112
+ for package_config in self.get_package_configs():
113
+ package_config.ready()
112
114
 
113
115
  self.clear_cache()
114
116
 
115
117
  self.models_ready = True
116
118
 
117
- # Phase 3: run ready() methods of app configs.
118
- for package_config in self.get_package_configs():
119
- package_config.ready()
120
-
121
119
  self.ready = True
122
120
 
123
121
  def check_packages_ready(self):
@@ -160,7 +158,9 @@ class Packages:
160
158
 
161
159
  # This method is performance-critical at least for Plain's test suite.
162
160
  @functools.cache
163
- def get_models(self, include_auto_created=False, include_swapped=False):
161
+ def get_models(
162
+ self, *, package_label="", include_auto_created=False, include_swapped=False
163
+ ):
164
164
  """
165
165
  Return a list of all installed models.
166
166
 
@@ -175,10 +175,27 @@ class Packages:
175
175
  self.check_models_ready()
176
176
 
177
177
  result = []
178
- for package_config in self.package_configs.values():
179
- result.extend(
180
- package_config.get_models(include_auto_created, include_swapped)
181
- )
178
+
179
+ # Get models for a single package
180
+ if package_label:
181
+ package_models = self.all_models[package_label]
182
+ for model in package_models.values():
183
+ if model._meta.auto_created and not include_auto_created:
184
+ continue
185
+ if model._meta.swapped and not include_swapped:
186
+ continue
187
+ result.append(model)
188
+ return result
189
+
190
+ # Get models for all packages
191
+ for package_models in self.all_models.values():
192
+ for model in package_models.values():
193
+ if model._meta.auto_created and not include_auto_created:
194
+ continue
195
+ if model._meta.swapped and not include_swapped:
196
+ continue
197
+ result.append(model)
198
+
182
199
  return result
183
200
 
184
201
  def get_model(self, package_label, model_name=None, require_ready=True):
@@ -201,12 +218,13 @@ class Packages:
201
218
  if model_name is None:
202
219
  package_label, model_name = package_label.split(".")
203
220
 
204
- package_config = self.get_package_config(package_label)
221
+ # package_config = self.get_package_config(package_label)
205
222
 
206
- if not require_ready and package_config.models is None:
207
- package_config.import_models()
223
+ # if not require_ready and package_config.models is None:
224
+ # package_config.import_models()
208
225
 
209
- return package_config.get_model(model_name, require_ready=require_ready)
226
+ package_models = self.all_models[package_label]
227
+ return package_models[model_name.lower()]
210
228
 
211
229
  def register_model(self, package_label, model):
212
230
  # Since this method is called when models are imported, it cannot
@@ -301,8 +319,8 @@ class Packages:
301
319
  if self.ready:
302
320
  # Circumvent self.get_models() to prevent that the cache is refilled.
303
321
  # This particularly prevents that an empty value is cached while cloning.
304
- for package_config in self.package_configs.values():
305
- for model in package_config.get_models(include_auto_created=True):
322
+ for package_models in self.all_models.values():
323
+ for model in package_models.values():
306
324
  model._meta._expire_cache()
307
325
 
308
326
  def lazy_model_operation(self, function, *model_keys):
@@ -355,4 +373,4 @@ class Packages:
355
373
  function(model)
356
374
 
357
375
 
358
- packages = Packages(installed_packages=None)
376
+ packages_registry = PackagesRegistry(installed_packages=None)
plain/runtime/__init__.py CHANGED
@@ -33,7 +33,7 @@ def setup():
33
33
  entry_point.load()()
34
34
 
35
35
  from plain.logs import configure_logging
36
- from plain.packages import packages
36
+ from plain.packages import packages_registry
37
37
 
38
38
  if not APP_PATH.exists():
39
39
  raise AppPathNotFound(
@@ -48,7 +48,7 @@ def setup():
48
48
 
49
49
  configure_logging(settings.LOGGING)
50
50
 
51
- packages.populate(settings.INSTALLED_PACKAGES)
51
+ packages_registry.populate(settings.INSTALLED_PACKAGES)
52
52
 
53
53
 
54
54
  __all__ = [
@@ -1,6 +1,6 @@
1
1
  from importlib import import_module
2
2
 
3
- from plain.packages import packages
3
+ from plain.packages import packages_registry
4
4
  from plain.runtime import settings
5
5
  from plain.utils.functional import LazyObject
6
6
  from plain.utils.module_loading import import_string, module_has_submodule
@@ -29,7 +29,7 @@ class JinjaEnvironment(LazyObject):
29
29
  import_module(name)
30
30
  self._imported_modules.add(name)
31
31
 
32
- for package_config in packages.get_package_configs():
32
+ for package_config in packages_registry.get_package_configs():
33
33
  if module_has_submodule(package_config.module, "templates"):
34
34
  # Allow this to fail in case there are import errors inside of their file
35
35
  _maybe_import_module(f"{package_config.name}.templates")
@@ -4,7 +4,7 @@ from pathlib import Path
4
4
  from jinja2 import Environment, StrictUndefined
5
5
  from jinja2.loaders import FileSystemLoader
6
6
 
7
- from plain.packages import packages
7
+ from plain.packages import packages_registry
8
8
  from plain.runtime import settings
9
9
 
10
10
  from .filters import default_filters
@@ -40,7 +40,7 @@ def _get_app_template_dirs():
40
40
  dirname = "templates"
41
41
  template_dirs = [
42
42
  Path(package_config.path) / dirname
43
- for package_config in packages.get_package_configs()
43
+ for package_config in packages_registry.get_package_configs()
44
44
  if package_config.path and (Path(package_config.path) / dirname).is_dir()
45
45
  ]
46
46
  # Immutable return value because it will be cached and shared by callers.
plain/urls/resolvers.py CHANGED
@@ -383,7 +383,7 @@ class URLResolver:
383
383
  else:
384
384
  lookup_view_s = lookup_view
385
385
 
386
- patterns = [pattern for (_, pattern, _, _) in possibilities]
386
+ patterns = [pos[1] for pos in possibilities]
387
387
  if patterns:
388
388
  if args:
389
389
  arg_msg = f"arguments '{args}'"
plain/urls/routers.py CHANGED
@@ -108,7 +108,7 @@ def path(route: str | re.Pattern, view: "View", *, name: str = "") -> URLPattern
108
108
  )
109
109
 
110
110
  # You typically pass a View class and we call as_view() for you
111
- if issubclass(view, View):
111
+ if isinstance(view, type) and issubclass(view, View):
112
112
  return URLPattern(pattern=pattern, view=view.as_view(), name=name)
113
113
 
114
114
  # If you called View.as_view() yourself (or technically any callable)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: plain
3
- Version: 0.23.1
3
+ Version: 0.24.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
@@ -10,15 +10,15 @@ plain/wsgi.py,sha256=R6k5FiAElvGDApEbMPTT0MPqSD7n2e2Az5chQqJZU0I,236
10
10
  plain/assets/README.md,sha256=048BzyQ2-BcsRiv6NiuLHHijOw96RK-e6lJ_Eq7g2pc,2857
11
11
  plain/assets/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
12
  plain/assets/compile.py,sha256=Qg-rMWykij_Jheq4THrPFWlmYv07ihHzWiNsD815HYE,3336
13
- plain/assets/finders.py,sha256=wMa0GUi4S5SUXKcWSqEesMgU4NbXXDrC4SMJwDakwNc,1215
13
+ plain/assets/finders.py,sha256=rhkHG5QW3H3IlBGHB5WJf9J6VTdDWgUC0qEs6u2Z4RQ,1233
14
14
  plain/assets/fingerprints.py,sha256=1NKAnnXVlncY5iimXztr0NL3RIjBKsNlZRIe6nmItJc,931
15
15
  plain/assets/urls.py,sha256=lW7VzKNzTKY11JqbszhJQ1Yy0HtljZlsHDnnkTPdLOM,992
16
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=0iHzlXWQTLxWxqxGV4f4K9ABT7s5q5gzSqoNzj0XuKg,18383
19
+ plain/cli/cli.py,sha256=40ewy2p3lyfgjrRrBU5QDBXd4BOtfejRO34nymNYmfc,18401
20
20
  plain/cli/formatting.py,sha256=1hZH13y1qwHcU2K2_Na388nw9uvoeQH8LrWL-O9h8Yc,2207
21
- plain/cli/packages.py,sha256=TiLirp0ccj5K96jOfp_pS18rOnk1aQS9ckiTi27aRwE,2740
21
+ plain/cli/packages.py,sha256=GLvDgQ1o93tSHae_B2i0YNimpt3LGu4QMQpFYrO48d8,2758
22
22
  plain/cli/print.py,sha256=XraUYrgODOJquIiEv78wSCYGRBplHXtXSS9QtFG5hqY,217
23
23
  plain/cli/startup.py,sha256=3LIz9JrIZoF52Sa0j0SCypQwEaBDkhvuGaBdtiQLr5Q,680
24
24
  plain/csrf/README.md,sha256=RXMWMtHmzf30gVVNOfj0kD4xlSqFIPgJh-n7dIciaEM,163
@@ -60,9 +60,9 @@ plain/logs/configure.py,sha256=6mV7d1IxkDYT3VBz61qhIj0Esuy5l5QdQfsHaGCfI6w,1063
60
60
  plain/logs/loggers.py,sha256=iz9SYcwP9w5QAuwpULl48SFkVyJuuMoQ_fdLgdCHpNg,2121
61
61
  plain/logs/utils.py,sha256=9UzdCCQXJinGDs71Ngw297mlWkhgZStSd67ya4NOW98,1257
62
62
  plain/packages/README.md,sha256=Vq1Nw3mmEmZ2IriQavuVi4BjcQC2nb8k7YIbnm8QjIg,799
63
- plain/packages/__init__.py,sha256=DnHN1wwHXiXib4Y9BV__x9WrbUaTovoTIxW-tVyScTU,106
64
- plain/packages/config.py,sha256=6j6Y9Uw4Lbye1M7LVgOhL4rAMkSSkleTzHQU9JRBW7k,11070
65
- plain/packages/registry.py,sha256=YMYGGrMWPoj4Bg_MXDVNnnoqOAufG_IBT24DB-twAgw,14860
63
+ plain/packages/__init__.py,sha256=75ILri5V7gm9k5RzvrYNBHPdLUZNbO65Go3kBg95O8w,124
64
+ plain/packages/config.py,sha256=oOXy_k2qzy1i221hCsayVx0xPVLBxb_pwOVDDxPVfDI,8842
65
+ plain/packages/registry.py,sha256=PeVoYbMwYqg7VTMB3QIWL3YUve9l2Ki-AJx29tm6SWs,15432
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
@@ -71,7 +71,7 @@ plain/preflight/registry.py,sha256=7s7f_iEwURzv-Ye515P5lJWcHltd5Ca2fsX1Wpbf1wQ,2
71
71
  plain/preflight/security.py,sha256=sNpv5AHobPcaO48cOUGRNe2EjusTducjY8vyShR8EhI,2645
72
72
  plain/preflight/urls.py,sha256=q3ikavMB8ZFMzzm_JOnm1YKwSONgaHjH4Is4-4mmTKM,3001
73
73
  plain/runtime/README.md,sha256=Q8VVO7JRGuYrDxzuYL6ptoilhclbecxKzpRXKgbWGkU,2061
74
- plain/runtime/__init__.py,sha256=ZfypqlhtbWUoJ84vLW4aKgpx2HsdtdJfDZnbbZw6kLE,1510
74
+ plain/runtime/__init__.py,sha256=FyGTIx-633bNPrPv8IBarBKvu_XspbCiqj8W8eOd_mA,1528
75
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
@@ -83,8 +83,8 @@ plain/templates/README.md,sha256=VfA2HmrklG5weE1md85q9g84cWnMBEiXAynKzM7S1Sk,464
83
83
  plain/templates/__init__.py,sha256=bX76FakE9T7mfK3N0deN85HlwHNQpeigytSC9Z8LcOs,451
84
84
  plain/templates/core.py,sha256=iw58EAmyyv8N5HDA-Sq4-fLgz_qx8v8WJfurgR116jw,625
85
85
  plain/templates/jinja/README.md,sha256=ft4781b4IAVI6fsIdAHIpOigdsZ6wGg06LK7BHxoj-g,6996
86
- plain/templates/jinja/__init__.py,sha256=jGjtygVB5Bwknpd3u_pBSrtUSGlFkYo6MDo0E3IWVrs,2653
87
- plain/templates/jinja/environments.py,sha256=T5e8rjVteN3-6IWCXNRsvPgMe0OVvTkX-r6_Q9gxhv8,2046
86
+ plain/templates/jinja/__init__.py,sha256=Nm34l_heWGYKFetO-GcAmr5qVbuQtyCJBy2jrEAoK-c,2671
87
+ plain/templates/jinja/environments.py,sha256=9plifzvQj--aTN1cCpJ2WdzQxZJpzB8S_4hghgQRQT0,2064
88
88
  plain/templates/jinja/extensions.py,sha256=AEmmmHDbdRW8fhjYDzq9eSSNbp9WHsXenD8tPthjc0s,1351
89
89
  plain/templates/jinja/filters.py,sha256=3KJKKbxcv9dLzUDWPcaa88k3NU2m1GG3iMIgFhzXrBA,860
90
90
  plain/templates/jinja/globals.py,sha256=VMpuMZvwWOmb5MbzKK-ox-QEX_WSsXFxq0mm8biJgaU,558
@@ -96,8 +96,8 @@ plain/urls/__init__.py,sha256=XF-W2GqLMA4bHbDRKnpZ7tiUtJ-BhWN-yAzw4nNnHdc,590
96
96
  plain/urls/converters.py,sha256=s2JZVOdzZC16lgobsI93hygcdH5L0Kj4742WEkXsVcs,1193
97
97
  plain/urls/exceptions.py,sha256=q4iPh3Aa-zHbA-tw8v6WyX1J1n5WdAady2xvxFuyXB0,114
98
98
  plain/urls/patterns.py,sha256=bU_xfhZbKMSgRG9OJ8w_NSuYRm_9zGnqoz_WY44fhUk,9358
99
- plain/urls/resolvers.py,sha256=bVh7risata9V7F42o7a1BL3GuxjBsmvI-kEFUi_U9zI,15488
100
- plain/urls/routers.py,sha256=RtOBeivHAJbaFW5DMu-gma47UKqyO9PSmxp_y5cTJCs,4029
99
+ plain/urls/resolvers.py,sha256=Jcve0_5G2IgLyMKA_cxccViQBhAkFS4X4Z-ozIXZM9w,15472
100
+ plain/urls/routers.py,sha256=J7v-o4BbTk_iPy_kMP_hOMNOPk-D2lockUmSD0Wx1R0,4056
101
101
  plain/urls/utils.py,sha256=WiGq6hHI-5DLFOxCQTAZ2qm0J-UdGosLcjuxlfK6_Tg,2137
102
102
  plain/utils/README.md,sha256=Bf5OG-MkOJDz_U8RGVreDfAI4M4nnPaLtk-LdinxHSc,99
103
103
  plain/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -138,8 +138,8 @@ plain/views/forms.py,sha256=RhlaUcZCkeqokY_fvv-NOS-kgZAG4XhDLOPbf9K_Zlc,2691
138
138
  plain/views/objects.py,sha256=g5Lzno0Zsv0K449UpcCtxwCoO7WMRAWqKlxxV2V0_qg,8263
139
139
  plain/views/redirect.py,sha256=9zHZgKvtSkdrMX9KmsRM8hJTPmBktxhc4d8OitbuniI,1724
140
140
  plain/views/templates.py,sha256=cBkFNCSXgVi8cMqQbhsqJ4M_rIQYVl8cUvq9qu4YIes,1951
141
- plain-0.23.1.dist-info/METADATA,sha256=TUFZYFXgCDf5COBQJ_to2OF_1rQKEly9mwlLEsgROBs,319
142
- plain-0.23.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
143
- plain-0.23.1.dist-info/entry_points.txt,sha256=DHHprvufgd7xypiBiqMANYRnpJ9xPPYhYbnPGwOkWqE,40
144
- plain-0.23.1.dist-info/licenses/LICENSE,sha256=m0D5O7QoH9l5Vz_rrX_9r-C8d9UNr_ciK6Qwac7o6yo,3175
145
- plain-0.23.1.dist-info/RECORD,,
141
+ plain-0.24.0.dist-info/METADATA,sha256=X4WLjJIco22nM723QFl9QslXEbSHHjNhDf4Oqqpr9Fw,319
142
+ plain-0.24.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
143
+ plain-0.24.0.dist-info/entry_points.txt,sha256=DHHprvufgd7xypiBiqMANYRnpJ9xPPYhYbnPGwOkWqE,40
144
+ plain-0.24.0.dist-info/licenses/LICENSE,sha256=m0D5O7QoH9l5Vz_rrX_9r-C8d9UNr_ciK6Qwac7o6yo,3175
145
+ plain-0.24.0.dist-info/RECORD,,
File without changes