2009-08-11 22:19:06 +00:00
|
|
|
#!/usr/bin/python
|
|
|
|
# Terminator by Chris Jones <cmsj@tenshu.net>
|
|
|
|
# GPL v2 only
|
|
|
|
"""borg.py - We are the borg. Resistance is futile.
|
2009-12-11 14:43:19 +00:00
|
|
|
http://code.activestate.com/recipes/66531/
|
2009-12-19 15:07:22 +00:00
|
|
|
ActiveState's policy appears to be that snippets
|
|
|
|
exist to encourage re-use, but I can not find any
|
|
|
|
specific licencing terms.
|
2009-12-11 14:43:19 +00:00
|
|
|
|
|
|
|
>>> obj1 = TestBorg()
|
|
|
|
>>> obj2 = TestBorg()
|
|
|
|
>>> obj1.attribute
|
|
|
|
0
|
|
|
|
>>> obj2.attribute
|
|
|
|
0
|
|
|
|
>>> obj1.attribute = 12345
|
|
|
|
>>> obj1.attribute
|
|
|
|
12345
|
|
|
|
>>> obj2.attribute
|
|
|
|
12345
|
|
|
|
>>> obj2.attribute = 54321
|
|
|
|
>>> obj1.attribute
|
|
|
|
54321
|
2009-12-22 00:24:03 +00:00
|
|
|
>>> obj3 = TestBorg2()
|
|
|
|
>>> obj3.attribute
|
|
|
|
1
|
|
|
|
>>> obj4 = TestBorg2()
|
|
|
|
>>> obj3.attribute = 98765
|
|
|
|
>>> obj4.attribute
|
|
|
|
98765
|
|
|
|
>>>
|
|
|
|
|
2009-12-11 14:43:19 +00:00
|
|
|
"""
|
2009-08-11 22:19:06 +00:00
|
|
|
|
2009-12-22 00:24:03 +00:00
|
|
|
from util import dbg
|
|
|
|
|
2009-08-11 22:23:34 +00:00
|
|
|
# pylint: disable-msg=R0903
|
2009-12-09 13:22:34 +00:00
|
|
|
# pylint: disable-msg=R0921
|
2009-08-11 22:19:06 +00:00
|
|
|
class Borg:
|
2009-10-09 11:25:06 +00:00
|
|
|
"""Definition of a class that can never be duplicated. Correct usage is
|
|
|
|
thus:
|
|
|
|
|
|
|
|
from borg import Borg
|
|
|
|
class foo(Borg):
|
|
|
|
# All attributes on a borg class *must* = None
|
|
|
|
attribute = None
|
|
|
|
|
|
|
|
def __init__(self):
|
2009-12-22 00:24:03 +00:00
|
|
|
Borg.__init__(self, self.__class__.__name__)
|
2009-10-09 11:25:06 +00:00
|
|
|
|
|
|
|
def prepare_attributes(self):
|
|
|
|
if not self.attribute:
|
|
|
|
self.attribute = []
|
|
|
|
|
|
|
|
bar = foo()
|
|
|
|
bar.prepare_attributes()
|
|
|
|
|
|
|
|
The important thing to note is that all attributes of borg classes *must* be
|
|
|
|
declared as being None. If you attempt to use static class attributes you
|
|
|
|
will get unpredicted behaviour. Instead, prepare_attributes() must be called
|
|
|
|
which will then see the attributes in the shared state, and initialise them
|
|
|
|
if necessary."""
|
2009-08-11 22:19:06 +00:00
|
|
|
__shared_state = {}
|
2009-10-09 11:25:06 +00:00
|
|
|
|
2009-12-22 00:24:03 +00:00
|
|
|
def __init__(self, borgtype=None):
|
2009-10-09 11:25:06 +00:00
|
|
|
"""Class initialiser. Overwrite our class dictionary with the shared
|
|
|
|
state. This makes us identical to every other instance of this class
|
|
|
|
type."""
|
2009-12-22 00:24:03 +00:00
|
|
|
if borgtype is None:
|
|
|
|
raise TypeError('Borg::__init__: You must pass a borgtype')
|
|
|
|
if not self.__shared_state.has_key(borgtype):
|
|
|
|
dbg('Borg::__init__: Preparing borg state for %s' % borgtype)
|
|
|
|
self.__shared_state[borgtype] = {}
|
|
|
|
self.__dict__ = self.__shared_state[borgtype]
|
2009-08-11 22:19:06 +00:00
|
|
|
|
2009-10-09 11:25:06 +00:00
|
|
|
def prepare_attributes(self):
|
|
|
|
"""This should be used to prepare any attributes of the borg class."""
|
|
|
|
raise NotImplementedError('prepare_attributes')
|
|
|
|
|
2009-12-11 14:43:19 +00:00
|
|
|
if __name__ == '__main__':
|
|
|
|
class TestBorg(Borg):
|
|
|
|
attribute = None
|
|
|
|
|
|
|
|
def __init__(self):
|
2009-12-22 00:24:03 +00:00
|
|
|
Borg.__init__(self, self.__class__.__name__)
|
2009-12-11 14:43:19 +00:00
|
|
|
self.prepare_attributes()
|
|
|
|
|
|
|
|
def prepare_attributes(self):
|
|
|
|
if not self.attribute:
|
|
|
|
self.attribute = 0
|
|
|
|
|
2009-12-22 00:24:03 +00:00
|
|
|
class TestBorg2(Borg):
|
|
|
|
attribute = None
|
|
|
|
|
|
|
|
def __init__(self):
|
|
|
|
Borg.__init__(self, self.__class__.__name__)
|
|
|
|
self.prepare_attributes()
|
|
|
|
|
|
|
|
def prepare_attributes(self):
|
|
|
|
if not self.attribute:
|
|
|
|
self.attribute = 1
|
|
|
|
|
2009-12-11 14:43:19 +00:00
|
|
|
import doctest
|
|
|
|
(failed, attempted) = doctest.testmod()
|
|
|
|
print "%d/%d tests failed" % (failed, attempted)
|
|
|
|
|