plain 0.23.0__tar.gz → 0.23.2__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 (157) hide show
  1. {plain-0.23.0 → plain-0.23.2}/PKG-INFO +1 -1
  2. {plain-0.23.0 → plain-0.23.2}/plain/assets/finders.py +2 -2
  3. {plain-0.23.0 → plain-0.23.2}/plain/cli/cli.py +2 -2
  4. {plain-0.23.0 → plain-0.23.2}/plain/cli/packages.py +2 -2
  5. plain-0.23.2/plain/packages/__init__.py +4 -0
  6. {plain-0.23.0 → plain-0.23.2}/plain/packages/config.py +1 -58
  7. {plain-0.23.0 → plain-0.23.2}/plain/packages/registry.py +40 -22
  8. {plain-0.23.0 → plain-0.23.2}/plain/runtime/__init__.py +2 -2
  9. {plain-0.23.0 → plain-0.23.2}/plain/templates/jinja/__init__.py +2 -2
  10. {plain-0.23.0 → plain-0.23.2}/plain/templates/jinja/environments.py +2 -2
  11. {plain-0.23.0 → plain-0.23.2}/plain/templates/jinja/globals.py +3 -0
  12. {plain-0.23.0 → plain-0.23.2}/plain/urls/routers.py +1 -1
  13. {plain-0.23.0 → plain-0.23.2}/pyproject.toml +1 -1
  14. plain-0.23.0/plain/packages/__init__.py +0 -4
  15. {plain-0.23.0 → plain-0.23.2}/.gitignore +0 -0
  16. {plain-0.23.0 → plain-0.23.2}/LICENSE +0 -0
  17. {plain-0.23.0 → plain-0.23.2}/README.md +0 -0
  18. {plain-0.23.0 → plain-0.23.2}/plain/README.md +0 -0
  19. {plain-0.23.0 → plain-0.23.2}/plain/__main__.py +0 -0
  20. {plain-0.23.0 → plain-0.23.2}/plain/assets/README.md +0 -0
  21. {plain-0.23.0 → plain-0.23.2}/plain/assets/__init__.py +0 -0
  22. {plain-0.23.0 → plain-0.23.2}/plain/assets/compile.py +0 -0
  23. {plain-0.23.0 → plain-0.23.2}/plain/assets/fingerprints.py +0 -0
  24. {plain-0.23.0 → plain-0.23.2}/plain/assets/urls.py +0 -0
  25. {plain-0.23.0 → plain-0.23.2}/plain/assets/views.py +0 -0
  26. {plain-0.23.0 → plain-0.23.2}/plain/cli/README.md +0 -0
  27. {plain-0.23.0 → plain-0.23.2}/plain/cli/__init__.py +0 -0
  28. {plain-0.23.0 → plain-0.23.2}/plain/cli/formatting.py +0 -0
  29. {plain-0.23.0 → plain-0.23.2}/plain/cli/print.py +0 -0
  30. {plain-0.23.0 → plain-0.23.2}/plain/cli/startup.py +0 -0
  31. {plain-0.23.0 → plain-0.23.2}/plain/csrf/README.md +0 -0
  32. {plain-0.23.0 → plain-0.23.2}/plain/csrf/middleware.py +0 -0
  33. {plain-0.23.0 → plain-0.23.2}/plain/csrf/views.py +0 -0
  34. {plain-0.23.0 → plain-0.23.2}/plain/debug.py +0 -0
  35. {plain-0.23.0 → plain-0.23.2}/plain/exceptions.py +0 -0
  36. {plain-0.23.0 → plain-0.23.2}/plain/forms/README.md +0 -0
  37. {plain-0.23.0 → plain-0.23.2}/plain/forms/__init__.py +0 -0
  38. {plain-0.23.0 → plain-0.23.2}/plain/forms/boundfield.py +0 -0
  39. {plain-0.23.0 → plain-0.23.2}/plain/forms/exceptions.py +0 -0
  40. {plain-0.23.0 → plain-0.23.2}/plain/forms/fields.py +0 -0
  41. {plain-0.23.0 → plain-0.23.2}/plain/forms/forms.py +0 -0
  42. {plain-0.23.0 → plain-0.23.2}/plain/http/README.md +0 -0
  43. {plain-0.23.0 → plain-0.23.2}/plain/http/__init__.py +0 -0
  44. {plain-0.23.0 → plain-0.23.2}/plain/http/cookie.py +0 -0
  45. {plain-0.23.0 → plain-0.23.2}/plain/http/multipartparser.py +0 -0
  46. {plain-0.23.0 → plain-0.23.2}/plain/http/request.py +0 -0
  47. {plain-0.23.0 → plain-0.23.2}/plain/http/response.py +0 -0
  48. {plain-0.23.0 → plain-0.23.2}/plain/internal/__init__.py +0 -0
  49. {plain-0.23.0 → plain-0.23.2}/plain/internal/files/README.md +0 -0
  50. {plain-0.23.0 → plain-0.23.2}/plain/internal/files/__init__.py +0 -0
  51. {plain-0.23.0 → plain-0.23.2}/plain/internal/files/base.py +0 -0
  52. {plain-0.23.0 → plain-0.23.2}/plain/internal/files/locks.py +0 -0
  53. {plain-0.23.0 → plain-0.23.2}/plain/internal/files/move.py +0 -0
  54. {plain-0.23.0 → plain-0.23.2}/plain/internal/files/temp.py +0 -0
  55. {plain-0.23.0 → plain-0.23.2}/plain/internal/files/uploadedfile.py +0 -0
  56. {plain-0.23.0 → plain-0.23.2}/plain/internal/files/uploadhandler.py +0 -0
  57. {plain-0.23.0 → plain-0.23.2}/plain/internal/files/utils.py +0 -0
  58. {plain-0.23.0 → plain-0.23.2}/plain/internal/handlers/__init__.py +0 -0
  59. {plain-0.23.0 → plain-0.23.2}/plain/internal/handlers/base.py +0 -0
  60. {plain-0.23.0 → plain-0.23.2}/plain/internal/handlers/exception.py +0 -0
  61. {plain-0.23.0 → plain-0.23.2}/plain/internal/handlers/wsgi.py +0 -0
  62. {plain-0.23.0 → plain-0.23.2}/plain/internal/middleware/__init__.py +0 -0
  63. {plain-0.23.0 → plain-0.23.2}/plain/internal/middleware/headers.py +0 -0
  64. {plain-0.23.0 → plain-0.23.2}/plain/internal/middleware/https.py +0 -0
  65. {plain-0.23.0 → plain-0.23.2}/plain/internal/middleware/slash.py +0 -0
  66. {plain-0.23.0 → plain-0.23.2}/plain/json.py +0 -0
  67. {plain-0.23.0 → plain-0.23.2}/plain/logs/README.md +0 -0
  68. {plain-0.23.0 → plain-0.23.2}/plain/logs/__init__.py +0 -0
  69. {plain-0.23.0 → plain-0.23.2}/plain/logs/configure.py +0 -0
  70. {plain-0.23.0 → plain-0.23.2}/plain/logs/loggers.py +0 -0
  71. {plain-0.23.0 → plain-0.23.2}/plain/logs/utils.py +0 -0
  72. {plain-0.23.0 → plain-0.23.2}/plain/packages/README.md +0 -0
  73. {plain-0.23.0 → plain-0.23.2}/plain/paginator.py +0 -0
  74. {plain-0.23.0 → plain-0.23.2}/plain/preflight/README.md +0 -0
  75. {plain-0.23.0 → plain-0.23.2}/plain/preflight/__init__.py +0 -0
  76. {plain-0.23.0 → plain-0.23.2}/plain/preflight/files.py +0 -0
  77. {plain-0.23.0 → plain-0.23.2}/plain/preflight/messages.py +0 -0
  78. {plain-0.23.0 → plain-0.23.2}/plain/preflight/registry.py +0 -0
  79. {plain-0.23.0 → plain-0.23.2}/plain/preflight/security.py +0 -0
  80. {plain-0.23.0 → plain-0.23.2}/plain/preflight/urls.py +0 -0
  81. {plain-0.23.0 → plain-0.23.2}/plain/runtime/README.md +0 -0
  82. {plain-0.23.0 → plain-0.23.2}/plain/runtime/global_settings.py +0 -0
  83. {plain-0.23.0 → plain-0.23.2}/plain/runtime/user_settings.py +0 -0
  84. {plain-0.23.0 → plain-0.23.2}/plain/signals/README.md +0 -0
  85. {plain-0.23.0 → plain-0.23.2}/plain/signals/__init__.py +0 -0
  86. {plain-0.23.0 → plain-0.23.2}/plain/signals/dispatch/__init__.py +0 -0
  87. {plain-0.23.0 → plain-0.23.2}/plain/signals/dispatch/dispatcher.py +0 -0
  88. {plain-0.23.0 → plain-0.23.2}/plain/signals/dispatch/license.txt +0 -0
  89. {plain-0.23.0 → plain-0.23.2}/plain/signing.py +0 -0
  90. {plain-0.23.0 → plain-0.23.2}/plain/templates/README.md +0 -0
  91. {plain-0.23.0 → plain-0.23.2}/plain/templates/__init__.py +0 -0
  92. {plain-0.23.0 → plain-0.23.2}/plain/templates/core.py +0 -0
  93. {plain-0.23.0 → plain-0.23.2}/plain/templates/jinja/README.md +0 -0
  94. {plain-0.23.0 → plain-0.23.2}/plain/templates/jinja/extensions.py +0 -0
  95. {plain-0.23.0 → plain-0.23.2}/plain/templates/jinja/filters.py +0 -0
  96. {plain-0.23.0 → plain-0.23.2}/plain/test/README.md +0 -0
  97. {plain-0.23.0 → plain-0.23.2}/plain/test/__init__.py +0 -0
  98. {plain-0.23.0 → plain-0.23.2}/plain/test/client.py +0 -0
  99. {plain-0.23.0 → plain-0.23.2}/plain/urls/README.md +0 -0
  100. {plain-0.23.0 → plain-0.23.2}/plain/urls/__init__.py +0 -0
  101. {plain-0.23.0 → plain-0.23.2}/plain/urls/converters.py +0 -0
  102. {plain-0.23.0 → plain-0.23.2}/plain/urls/exceptions.py +0 -0
  103. {plain-0.23.0 → plain-0.23.2}/plain/urls/patterns.py +0 -0
  104. {plain-0.23.0 → plain-0.23.2}/plain/urls/resolvers.py +0 -0
  105. {plain-0.23.0 → plain-0.23.2}/plain/urls/utils.py +0 -0
  106. {plain-0.23.0 → plain-0.23.2}/plain/utils/README.md +0 -0
  107. {plain-0.23.0 → plain-0.23.2}/plain/utils/__init__.py +0 -0
  108. {plain-0.23.0 → plain-0.23.2}/plain/utils/_os.py +0 -0
  109. {plain-0.23.0 → plain-0.23.2}/plain/utils/cache.py +0 -0
  110. {plain-0.23.0 → plain-0.23.2}/plain/utils/connection.py +0 -0
  111. {plain-0.23.0 → plain-0.23.2}/plain/utils/crypto.py +0 -0
  112. {plain-0.23.0 → plain-0.23.2}/plain/utils/datastructures.py +0 -0
  113. {plain-0.23.0 → plain-0.23.2}/plain/utils/dateformat.py +0 -0
  114. {plain-0.23.0 → plain-0.23.2}/plain/utils/dateparse.py +0 -0
  115. {plain-0.23.0 → plain-0.23.2}/plain/utils/dates.py +0 -0
  116. {plain-0.23.0 → plain-0.23.2}/plain/utils/deconstruct.py +0 -0
  117. {plain-0.23.0 → plain-0.23.2}/plain/utils/decorators.py +0 -0
  118. {plain-0.23.0 → plain-0.23.2}/plain/utils/duration.py +0 -0
  119. {plain-0.23.0 → plain-0.23.2}/plain/utils/email.py +0 -0
  120. {plain-0.23.0 → plain-0.23.2}/plain/utils/encoding.py +0 -0
  121. {plain-0.23.0 → plain-0.23.2}/plain/utils/functional.py +0 -0
  122. {plain-0.23.0 → plain-0.23.2}/plain/utils/hashable.py +0 -0
  123. {plain-0.23.0 → plain-0.23.2}/plain/utils/html.py +0 -0
  124. {plain-0.23.0 → plain-0.23.2}/plain/utils/http.py +0 -0
  125. {plain-0.23.0 → plain-0.23.2}/plain/utils/inspect.py +0 -0
  126. {plain-0.23.0 → plain-0.23.2}/plain/utils/ipv6.py +0 -0
  127. {plain-0.23.0 → plain-0.23.2}/plain/utils/itercompat.py +0 -0
  128. {plain-0.23.0 → plain-0.23.2}/plain/utils/module_loading.py +0 -0
  129. {plain-0.23.0 → plain-0.23.2}/plain/utils/regex_helper.py +0 -0
  130. {plain-0.23.0 → plain-0.23.2}/plain/utils/safestring.py +0 -0
  131. {plain-0.23.0 → plain-0.23.2}/plain/utils/text.py +0 -0
  132. {plain-0.23.0 → plain-0.23.2}/plain/utils/timesince.py +0 -0
  133. {plain-0.23.0 → plain-0.23.2}/plain/utils/timezone.py +0 -0
  134. {plain-0.23.0 → plain-0.23.2}/plain/utils/tree.py +0 -0
  135. {plain-0.23.0 → plain-0.23.2}/plain/validators.py +0 -0
  136. {plain-0.23.0 → plain-0.23.2}/plain/views/README.md +0 -0
  137. {plain-0.23.0 → plain-0.23.2}/plain/views/__init__.py +0 -0
  138. {plain-0.23.0 → plain-0.23.2}/plain/views/base.py +0 -0
  139. {plain-0.23.0 → plain-0.23.2}/plain/views/csrf.py +0 -0
  140. {plain-0.23.0 → plain-0.23.2}/plain/views/errors.py +0 -0
  141. {plain-0.23.0 → plain-0.23.2}/plain/views/exceptions.py +0 -0
  142. {plain-0.23.0 → plain-0.23.2}/plain/views/forms.py +0 -0
  143. {plain-0.23.0 → plain-0.23.2}/plain/views/objects.py +0 -0
  144. {plain-0.23.0 → plain-0.23.2}/plain/views/redirect.py +0 -0
  145. {plain-0.23.0 → plain-0.23.2}/plain/views/templates.py +0 -0
  146. {plain-0.23.0 → plain-0.23.2}/plain/wsgi.py +0 -0
  147. {plain-0.23.0 → plain-0.23.2}/tests/.bolt/assets_collected/assets.json +0 -0
  148. {plain-0.23.0 → plain-0.23.2}/tests/.gitignore +0 -0
  149. {plain-0.23.0 → plain-0.23.2}/tests/app/.gitignore +0 -0
  150. {plain-0.23.0 → plain-0.23.2}/tests/app/settings.py +0 -0
  151. {plain-0.23.0 → plain-0.23.2}/tests/app/test/__init__.py +0 -0
  152. {plain-0.23.0 → plain-0.23.2}/tests/app/test/default_settings.py +0 -0
  153. {plain-0.23.0 → plain-0.23.2}/tests/app/urls.py +0 -0
  154. {plain-0.23.0 → plain-0.23.2}/tests/conftest.py +0 -0
  155. {plain-0.23.0 → plain-0.23.2}/tests/test_cli.py +0 -0
  156. {plain-0.23.0 → plain-0.23.2}/tests/test_runtime.py +0 -0
  157. {plain-0.23.0 → plain-0.23.2}/tests/test_wsgi.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: plain
3
- Version: 0.23.0
3
+ Version: 0.23.2
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
@@ -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
@@ -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
@@ -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
 
@@ -0,0 +1,4 @@
1
+ from .config import PackageConfig
2
+ from .registry import packages_registry
3
+
4
+ __all__ = ["PackageConfig", "packages_registry"]
@@ -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)
@@ -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.
@@ -1,3 +1,5 @@
1
+ from datetime import timedelta
2
+
1
3
  from plain.paginator import Paginator
2
4
  from plain.urls import reverse
3
5
  from plain.utils import timezone
@@ -16,5 +18,6 @@ default_globals = {
16
18
  "url": reverse,
17
19
  "Paginator": Paginator,
18
20
  "now": timezone.now,
21
+ "timedelta": timedelta,
19
22
  "localtime": timezone.localtime,
20
23
  }
@@ -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
  [project]
2
2
  name = "plain"
3
- version = "0.23.0"
3
+ version = "0.23.2"
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"
@@ -1,4 +0,0 @@
1
- from .config import PackageConfig
2
- from .registry import packages
3
-
4
- __all__ = ["PackageConfig", "packages"]
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