Browse code
Fixed various problems with <registry.py>
Ed L authored on 03/03/2012 23:31:34
Showing 1 changed files
Showing 1 changed files
... | ... |
@@ -32,57 +32,43 @@ import contextlib |
32 | 32 |
import functools |
33 | 33 |
|
34 | 34 |
class CallableGeneratorContextManager(contextlib.GeneratorContextManager): |
35 |
+ '''A subclass of :py:class:`contextlib.GeneratorContextManager` which can be called |
|
36 |
+ |
|
37 |
+ Basically, this exists to avoid unecessary hassles with object methods which need special treatment''' |
|
35 | 38 |
def __call__(self, *a, **kw): |
39 |
+ '''Enter self's context and call the object returned by __enter__''' |
|
36 | 40 |
with self as obj: |
37 | 41 |
return obj(*a, **kw) |
38 |
-try: |
|
39 |
- from contextlib import contextmanager |
|
40 |
-except: |
|
41 |
- def contextmanager(func): |
|
42 |
- """@contextmanager decorator. |
|
43 |
- |
|
44 |
- Typical usage: |
|
45 |
- |
|
46 |
- @contextmanager |
|
47 |
- def some_generator(<arguments>): |
|
48 |
- <setup> |
|
49 |
- try: |
|
50 |
- yield <value> |
|
51 |
- finally: |
|
52 |
- <cleanup> |
|
53 |
- |
|
54 |
- This makes this: |
|
55 |
- |
|
56 |
- with some_generator(<arguments>) as <variable>: |
|
57 |
- <body> |
|
58 |
- |
|
59 |
- equivalent to this: |
|
60 | 42 |
|
61 |
- <setup> |
|
62 |
- try: |
|
63 |
- <variable> = <value> |
|
64 |
- <body> |
|
65 |
- finally: |
|
66 |
- <cleanup> |
|
67 |
- |
|
68 |
- """ |
|
69 |
- @functools.wraps(func) |
|
70 |
- def helper(*args, **kwds): |
|
71 |
- return CallableGeneratorContextManager(func(*args, **kwds)) |
|
72 |
- return helper |
|
43 |
+#NOTE: (ed) this is ripped out of contextlib but I've replaced contextlib.GeneratorContextManager with the previous class |
|
44 |
+def contextmanager(func): |
|
45 |
+ '''see documentation for :py:class:`contextlib.GeneratorContextManager`''' |
|
46 |
+ @functools.wraps(func) |
|
47 |
+ def helper(*args, **kwds): |
|
48 |
+ return CallableGeneratorContextManager(func(*args, **kwds)) |
|
49 |
+ # ^^^ This is the only line diferent from contextlib.contextmanager |
|
50 |
+ return helper |
|
73 | 51 |
|
74 | 52 |
|
75 | 53 |
class RegisteredObj(object): |
54 |
+ '''Interface definition for :py:attr:`Registry.child_class`''' |
|
76 | 55 |
def __init__(self, name, *args): |
77 | 56 |
self.name = name |
78 | 57 |
|
79 | 58 |
def update(self, other): |
59 |
+ '''override me''' |
|
80 | 60 |
pass |
81 | 61 |
|
82 | 62 |
def make_ctxt_manager(name): |
63 |
+ '''create a factory method for making and registering objects suitable to be registered in |
|
64 |
+ the Registry. |
|
65 |
+ |
|
66 |
+ :param str name: The name of the factory method |
|
67 |
+ :return: A contextmanager |
|
68 |
+ ''' |
|
83 | 69 |
@contextmanager |
84 |
- def _inner(self, name, *args): |
|
85 |
- obj = self.registry.get(name) if name in self.registry else self.child_class(name, *args) |
|
70 |
+ def _inner(self, name, *args, **kwargs): |
|
71 |
+ obj = self.registry.get(name) if name in self.registry else self.child_class(name, *args, **kwargs) |
|
86 | 72 |
yield obj |
87 | 73 |
if obj.name not in self.registry: |
88 | 74 |
self.register(obj) |
... | ... |
@@ -92,6 +78,8 @@ def make_ctxt_manager(name): |
92 | 78 |
|
93 | 79 |
import threading |
94 | 80 |
class Registry(object): |
81 |
+ #: The kind of object to be stored in the registry |
|
82 |
+ #: must, as a minimum implement the :py:class:`RegisteredObj` interface |
|
95 | 83 |
child_class = None |
96 | 84 |
|
97 | 85 |
def __setitem__(self, name, value): |
... | ... |
@@ -119,6 +107,12 @@ class Registry(object): |
119 | 107 |
_init_lock = threading.RLock() |
120 | 108 |
@staticmethod |
121 | 109 |
def setup(cls): |
110 |
+ '''Decorate the registry with this, this sets the 'registry' attribute to an |
|
111 |
+ empty dictionary and a factory function for creating child objects. |
|
112 |
+ |
|
113 |
+ The name of the factory function is that of the class the registry registers, |
|
114 |
+ but lowercase''' |
|
115 |
+ |
|
122 | 116 |
with cls._init_lock: |
123 | 117 |
factory_name = cls.child_class.__name__.lower() |
124 | 118 |
setattr(cls, factory_name, make_ctxt_manager(factory_name)) |
... | ... |
@@ -139,6 +133,8 @@ class Registry(object): |
139 | 133 |
|
140 | 134 |
return result |
141 | 135 |
|
136 |
+### DEMO, read this for a practical example of how the above works: |
|
137 |
+ |
|
142 | 138 |
class DataObj(RegisteredObj): |
143 | 139 |
def __init__(self, name, a): |
144 | 140 |
RegisteredObj.__init__(self, name) |