Skip to content
This repository was archived by the owner on May 3, 2020. It is now read-only.

Commit 134c2b7

Browse files
committed
Merge pull request #19 from greut/mutablemapping
Using the collections abstract classes for list and dict.
2 parents 9f0e3e6 + 5d146f5 commit 134c2b7

File tree

9 files changed

+360
-394
lines changed

9 files changed

+360
-394
lines changed

flask_registry/__init__.py

Lines changed: 31 additions & 229 deletions
Original file line numberDiff line numberDiff line change
@@ -21,252 +21,54 @@
2121
## granted to it by virtue of its status as an Intergovernmental Organization
2222
## or submit itself to any jurisdiction.
2323

24-
"""
25-
Flask extension
26-
===============
24+
"""Flask extension.
2725
2826
Flask-Registry is initialized like this:
2927
30-
>>> from flask import Flask
31-
>>> from flask_registry import Registry, ListRegistry
32-
>>> app = Flask('myapp')
33-
>>> r = Registry(app=app)
34-
35-
A simple usage example of ``ListRegistry`` looks like this:
36-
37-
>>> app.extensions['registry']['my.namespace'] = ListRegistry()
38-
>>> len(app.extensions['registry'])
39-
1
40-
>>> app.extensions['registry']['my.namespace'].register("something")
41-
>>> app.extensions['registry']['my.namespace'].register("something else")
42-
>>> len(app.extensions['registry']['my.namespace'])
43-
2
44-
>>> for obj in app.extensions['registry']['my.namespace']:
45-
... print(obj)
46-
something
47-
something else
48-
"""
49-
50-
from __future__ import absolute_import
51-
52-
from werkzeug.local import LocalProxy
53-
from flask import current_app
54-
55-
56-
class RegistryError(Exception):
57-
"""
58-
Exception class raised for user errors (e.g. creating two registries in
59-
the same namespace)
60-
"""
61-
pass
62-
63-
64-
class Registry(object):
65-
"""
66-
Flask extension
67-
68-
Initialization of the extension:
28+
.. code-block:: pycon
6929
7030
>>> from flask import Flask
7131
>>> from flask_registry import Registry, ListRegistry
7232
>>> app = Flask('myapp')
7333
>>> r = Registry(app=app)
7434
75-
or alternatively using the factory pattern:
76-
77-
>>> app = Flask('myapp')
78-
>>> r = Registry()
79-
>>> r.init_app(app)
80-
"""
81-
def __init__(self, app=None):
82-
self._registry = dict()
83-
self.app = app
84-
if app is not None:
85-
self.init_app(app)
86-
87-
def init_app(self, app):
88-
"""
89-
Initialize a Flask application.
90-
91-
Only one Registry per application is allowed.
92-
"""
93-
# Follow the Flask guidelines on usage of app.extensions
94-
if not hasattr(app, 'extensions'):
95-
app.extensions = {}
96-
if 'registry' in app.extensions:
97-
raise RegistryError("Flask application already initialized")
98-
app.extensions['registry'] = self
99-
100-
def __iter__(self):
101-
"""
102-
Get iterator over registries.
103-
"""
104-
return self._registry.__iter__()
105-
106-
def __len__(self):
107-
"""
108-
Get number of registries.
109-
"""
110-
return self._registry.__len__()
111-
112-
def __contains__(self, item):
113-
"""
114-
Check if namespace exists in Flask application registry.
115-
116-
:param item: Namespace
117-
"""
118-
return self._registry.__contains__(item)
119-
120-
def __getitem__(self, key):
121-
"""
122-
Get a registry with a given namespace.
123-
124-
:param key: Namespace
125-
"""
126-
return self._registry[key]
127-
128-
def __delitem__(self, key):
129-
"""
130-
Remove a registry
131-
132-
:param key: Namespace
133-
"""
134-
obj = self._registry[key]
135-
del self._registry[key]
136-
obj.namespace = None
137-
138-
def __setitem__(self, key, value):
139-
"""
140-
Register a registry in the Flask application registry.
141-
142-
:param key: Namespace
143-
:param value: Instance of RegistryBase or subclass
144-
"""
145-
if key in self._registry:
146-
raise RegistryError("Namespace %s already taken." % key)
147-
self._registry[key] = value
148-
self._registry[key].namespace = key
149-
150-
def items(self):
151-
""" Get list of (namespace, registry)-pairs. """
152-
return self._registry.items()
153-
154-
155-
# pylint: disable=R0921
156-
class RegistryBase(object):
157-
"""
158-
Abstract base class for all registries.
159-
160-
Each subclass must implement the ``register()`` method.
161-
Each subclass may implement the ``unregister()`` method.
162-
163-
Once a registry is registered in the Flask application, the namespace
164-
under which it is available is injected into it self.
165-
166-
Please see ``flask_registry.registries.core`` for simple examples of
167-
subclasses.
168-
"""
169-
_namespace = None
170-
171-
@property
172-
def namespace(self):
173-
"""
174-
Namespace. Used only by the Flask extension to inject the namespace
175-
under which this instance is registered in the Flask application.
176-
Defaults to ``None`` if not registered in a Flask application.
177-
"""
178-
return self._namespace
179-
180-
@namespace.setter
181-
def namespace(self, value):
182-
""" Setter for namespace property. """
183-
if self._namespace and value is not None:
184-
raise RegistryError("Namespace cannot be changed.")
185-
self._namespace = value
186-
187-
def register(self, *args, **kwargs):
188-
"""
189-
Abstract method which MUST be overwritten by subclasses. A subclass
190-
does not need to take the same number of arguments as the abstract
191-
base class.
192-
"""
193-
raise NotImplementedError()
194-
195-
def unregister(self, *args, **kwargs):
196-
"""
197-
Abstract method which MAY be overwritten by subclasses. A subclass
198-
does not need to take the same number of arguments as the abstract
199-
base class.
200-
"""
201-
raise NotImplementedError()
202-
203-
204-
class RegistryProxy(LocalProxy):
205-
"""
206-
Lazy proxy object to a registry in the ``current_app``
207-
208-
Allows you to define a registry in your local module without needing to
209-
initialize it first. Once accessed the first time, the registry will be
210-
initialized in the current_app, thus you must be working in either
211-
the Flask application context or request context.
212-
213-
>>> from flask import Flask
214-
>>> app = Flask('myapp')
215-
>>> from flask_registry import Registry, RegistryProxy, RegistryBase
216-
>>> r = Registry(app=app)
217-
>>> proxy = RegistryProxy('myns', RegistryBase)
218-
>>> 'myns' in app.extensions['registry']
219-
False
220-
>>> with app.app_context():
221-
... print(proxy.namespace)
222-
...
223-
myns
224-
>>> 'myns' in app.extensions['registry']
225-
True
226-
227-
:param namespace: Namespace for registry
228-
:param registry_class: The registry class - i.e. a sublcass of
229-
``RegistryBase``.
230-
:param args: Arguments passed to ``registry_class`` on initialization.
231-
:param kwargs: Keyword arguments passed to ``registry_class`` on
232-
initialization.
233-
"""
35+
A simple usage example of ``ListRegistry`` looks like this:
23436
235-
# pylint: disable=W0142, C0111, E1002
236-
def __init__(self, namespace, registry_class, *args, **kwargs):
237-
def _lookup():
238-
if not 'registry' in getattr(current_app, 'extensions', {}):
239-
raise RegistryError('Registry is not initialized.')
240-
if namespace not in current_app.extensions['registry']:
241-
# pylint: disable=W0142
242-
current_app.extensions['registry'][namespace] = \
243-
registry_class(
244-
*args, **kwargs
245-
)
246-
return current_app.extensions['registry'][namespace]
247-
super(RegistryProxy, self).__init__(_lookup)
37+
.. code-block:: pycon
38+
39+
>>> app.extensions['registry']['my.namespace'] = ListRegistry()
40+
>>> len(app.extensions['registry'])
41+
1
42+
>>> app.extensions['registry']['my.namespace'].register("something")
43+
>>> app.extensions['registry']['my.namespace'].register("something else")
44+
>>> len(app.extensions['registry']['my.namespace'])
45+
2
46+
>>> for obj in app.extensions['registry']['my.namespace']:
47+
... print(obj)
48+
something
49+
something else
50+
"""
24851

52+
from .base import Registry, RegistryError, RegistryProxy, RegistryBase
53+
from .registries.core import (ListRegistry, DictRegistry,
54+
ImportPathRegistry, ModuleRegistry,
55+
SingletonRegistry)
56+
from .registries.modulediscovery import (ModuleDiscoveryRegistry,
57+
ModuleAutoDiscoveryRegistry)
58+
from .registries.pkgresources import (EntryPointRegistry,
59+
PkgResourcesDirDiscoveryRegistry)
60+
from .registries.appdiscovery import (PackageRegistry,
61+
ExtensionRegistry,
62+
ConfigurationRegistry,
63+
BlueprintAutoDiscoveryRegistry)
24964

250-
# Version information
25165
from .version import __version__
25266

253-
#
254-
# API of registries
255-
#
256-
from .registries.core import ListRegistry, DictRegistry, \
257-
ImportPathRegistry, ModuleRegistry, SingletonRegistry
258-
from .registries.modulediscovery import \
259-
ModuleDiscoveryRegistry, ModuleAutoDiscoveryRegistry
260-
from .registries.pkgresources import EntryPointRegistry, \
261-
PkgResourcesDirDiscoveryRegistry
262-
from .registries.appdiscovery import PackageRegistry, \
263-
ExtensionRegistry, ConfigurationRegistry, BlueprintAutoDiscoveryRegistry
264-
265-
__all__ = [
67+
__all__ = (
26668
'Registry', 'RegistryError', 'RegistryProxy', 'RegistryBase',
26769
'ListRegistry', 'DictRegistry', 'ImportPathRegistry', 'ModuleRegistry',
26870
'ModuleDiscoveryRegistry', 'ModuleAutoDiscoveryRegistry',
26971
'EntryPointRegistry', 'PkgResourcesDirDiscoveryRegistry',
27072
'PackageRegistry', 'ExtensionRegistry', 'ConfigurationRegistry',
27173
'BlueprintAutoDiscoveryRegistry', 'SingletonRegistry', '__version__'
272-
]
74+
)

0 commit comments

Comments
 (0)