git.fiddlerwoaroof.com
Browse code

Revert "added the registry class"

This reverts commit 86146028294bb9e499b968ad14cb7ccd4ec43fea.

edwlan authored on 22/07/2013 22:05:32
Showing 1 changed files
1 1
deleted file mode 100644
... ...
@@ -1,172 +0,0 @@
1
-# Copyright (c) 2011 Edward Langley
2
-# All rights reserved.
3
-# 
4
-# Redistribution and use in source and binary forms, with or without
5
-# modification, are permitted provided that the following conditions
6
-# are met:
7
-# 
8
-# Redistributions of source code must retain the above copyright notice,
9
-# this list of conditions and the following disclaimer.
10
-# 
11
-# Redistributions in binary form must reproduce the above copyright
12
-# notice, this list of conditions and the following disclaimer in the
13
-# documentation and/or other materials provided with the distribution.
14
-# 
15
-# Neither the name of the project's author nor the names of its
16
-# contributors may be used to endorse or promote products derived from
17
-# this software without specific prior written permission.
18
-# 
19
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22
-# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23
-# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
25
-# TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26
-# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27
-# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28
-# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29
-# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
-
31
-import contextlib
32
-import functools
33
-
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'''
38
-	def __call__(self, *a, **kw):
39
-		'''Enter self's context and call the object returned by __enter__'''
40
-		with self as obj:
41
-			return obj(*a, **kw)
42
-
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
51
-
52
-
53
-class RegisteredObj(object):
54
-	'''Interface definition for :py:attr:`Registry.child_class`'''
55
-	def __init__(self, name, *args):
56
-		self.name = name
57
-
58
-	def update(self, other):
59
-		'''override me'''
60
-		pass
61
-
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
-	'''
69
-	@contextmanager
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)
72
-		yield obj
73
-		if obj.name not in self.registry:
74
-			self.register(obj)
75
-
76
-	_inner.__name__ = name
77
-	return _inner
78
-
79
-import threading
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
83
-	child_class = None
84
-
85
-	def __setitem__(self, name, value):
86
-		with self._lock:
87
-			self.registry[name] = value
88
-
89
-	def __getitem__(self, name):
90
-		with self._lock:
91
-			return self.registry[name]
92
-
93
-	def __delitem__(self, name):
94
-		with self._lock:
95
-			del self.registry[name]
96
-
97
-	@classmethod
98
-	def reset(cls):
99
-		with cls._lock:
100
-			cls.registry.clear()
101
-
102
-	@classmethod
103
-	def get(cls, name, default=None):
104
-		with cls._lock:
105
-			return cls.registry.get(name, default)
106
-
107
-	_init_lock = threading.RLock()
108
-	@staticmethod
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
-
116
-		with cls._init_lock:
117
-			factory_name = cls.child_class.__name__.lower()
118
-			setattr(cls, factory_name, make_ctxt_manager(factory_name))
119
-			cls.registry = {}
120
-			cls._lock = threading.RLock()
121
-			return cls
122
-
123
-	def register(self, obj):
124
-		with self._lock:
125
-			old_obj = self.registry.get(obj.name)
126
-			result = obj
127
-
128
-			if old_obj is not None:
129
-				old_obj.update(obj)
130
-				result = old_obj
131
-			else:
132
-				self.registry[obj.name] = obj
133
-
134
-		return result
135
-
136
-### DEMO, read this for a practical example of how the above works:
137
-
138
-class DataObj(RegisteredObj):
139
-	def __init__(self, name, a):
140
-		RegisteredObj.__init__(self, name)
141
-		self.a = a
142
-		self.b = None
143
-		self.c = None
144
-
145
-@Registry.setup
146
-class DataObjRegistry(Registry):
147
-	child_class = DataObj
148
-
149
-if __name__ == '__main__':
150
-	#Demo code
151
-
152
-	registry = DataObjRegistry()
153
-	with registry.dataobj('first_obj', 1) as obj1:
154
-		obj1.b = 2
155
-
156
-	with registry.dataobj('second_obj', 2) as obj2:
157
-		obj2.b = 3
158
-		obj2.c = 4
159
-
160
-	with registry.dataobj('third_obj', 3) as obj3:
161
-		obj1.b = 4
162
-
163
-	import random
164
-	def shuffled(lis):
165
-	lis = lis[:]
166
-	random.shuffle(lis)
167
-	return iter(lis)
168
-
169
-
170
-	for obj_name in shuffled(['first_obj', 'second_obj', 'third_obj']):
171
-		with registry.dataobj(obj_name) as obj:
172
-			print '%s - a: %s, b: %s, c: %s' % (obj.name, obj.a, obj.b, obj.c)