2
0
Fork 0

fix: always use 'wutta' prefix for provider entry points

otherwise not all providers will be discoverable, for custom appname

also add `appname` prop for GenericHandler, AppProvider
This commit is contained in:
Lance Edgar 2024-07-14 10:45:13 -05:00
parent f6d0912c03
commit b4d6cfb0ed
2 changed files with 37 additions and 9 deletions

View file

@ -105,9 +105,6 @@ class AppHandler:
self.providers = self.get_all_providers()
return self.providers
# if 'providers' not in self.__dict__:
# self.__dict__['providers'] = self.get_all_providers()
for provider in self.providers.values():
if hasattr(provider, name):
return getattr(provider, name)
@ -121,10 +118,22 @@ class AppHandler:
Note that you do not need to call this directly; instead just
use :attr:`providers`.
The discovery logic is based on :term:`entry points<entry
point>` using the ``wutta.app.providers`` group. For instance
here is a sample entry point used by WuttaWeb (in its
``pyproject.toml``):
.. code-block:: toml
[project.entry-points."wutta.app.providers"]
wuttaweb = "wuttaweb.app:WebAppProvider"
:returns: Dictionary keyed by entry point name; values are
:class:`AppProvider` *instances*.
:class:`AppProvider` instances.
"""
providers = load_entry_points(f'{self.appname}.providers')
# nb. must use 'wutta' and not self.appname prefix here, or
# else we can't find all providers with custom appname
providers = load_entry_points('wutta.app.providers')
for key in list(providers):
providers[key] = providers[key](self.config)
return providers
@ -278,8 +287,7 @@ class AppProvider:
These can add arbitrary extra functionality to the main :term:`app
handler`. See also :doc:`/narr/providers/app`.
:param config: Config object for the app. This should be an
instance of :class:`~wuttjamaican.conf.WuttaConfig`.
:param config: The app :term:`config object`.
Instances have the following attributes:
@ -301,7 +309,16 @@ class AppProvider:
config = config.config
self.config = config
self.app = config.get_app()
self.app = self.config.get_app()
@property
def appname(self):
"""
The :term:`app name` for the current app.
See also :attr:`AppHandler.appname`.
"""
return self.app.appname
class GenericHandler:
@ -318,3 +335,12 @@ class GenericHandler:
def __init__(self, config, **kwargs):
self.config = config
self.app = self.config.get_app()
@property
def appname(self):
"""
The :term:`app name` for the current app.
See also :attr:`AppHandler.appname`.
"""
return self.app.appname

View file

@ -134,6 +134,7 @@ class TestAppProvider(TestCase):
provider = app.AppProvider(self.config)
self.assertIs(provider.config, self.config)
self.assertIs(provider.app, self.app)
self.assertEqual(provider.appname, 'wuttatest')
# but can pass app handler instead
with warnings.catch_warnings():
@ -155,7 +156,7 @@ class TestAppProvider(TestCase):
# sanity check, we get *instances* back from this
providers = self.app.get_all_providers()
load_entry_points.assert_called_once_with('wuttatest.providers')
load_entry_points.assert_called_once_with('wutta.app.providers')
self.assertEqual(len(providers), 1)
self.assertIn('fake', providers)
self.assertIsInstance(providers['fake'], FakeProvider)
@ -212,3 +213,4 @@ class TestGenericHandler(TestCase):
handler = app.GenericHandler(self.config)
self.assertIs(handler.config, self.config)
self.assertIs(handler.app, self.app)
self.assertEqual(handler.appname, 'wuttatest')