1655
by Stephen Boddy
Fix terminator not working with default python3 by forcing python2 |
1 |
#!/usr/bin/env python2
|
775.1.20
by Chris Jones
switch from a singleton to a borg, and don't do circular imports |
2 |
# Terminator by Chris Jones <cmsj@tenshu.net>
|
3 |
# GPL v2 only
|
|
4 |
"""borg.py - We are the borg. Resistance is futile.
|
|
1590
by Stephen Boddy
(trunk-1599/1600/1601) |
5 |
|
6 |
http://code.activestate.com/recipes/66531/
|
|
7 |
ActiveState's policy appears to be that snippets
|
|
8 |
exist to encourage re-use, but I can not find any
|
|
9 |
specific licencing terms.
|
|
775.1.174
by Chris Jones
who knows, we might even stick to a testing regime this time |
10 |
"""
|
775.1.20
by Chris Jones
switch from a singleton to a borg, and don't do circular imports |
11 |
|
775.1.189
by Chris Jones
extend test coverage to ensure borg state is unique between borg types. add some debugging info and support the ability to have multiple borg classes via an ugly parameter to __init__() |
12 |
from util import dbg |
13 |
||
775.1.21
by Chris Jones
appease pylint |
14 |
# pylint: disable-msg=R0903
|
775.1.166
by Chris Jones
pylint fixes |
15 |
# pylint: disable-msg=R0921
|
775.1.20
by Chris Jones
switch from a singleton to a borg, and don't do circular imports |
16 |
class Borg: |
775.1.92
by Chris Jones
Flesh out the borg a little |
17 |
"""Definition of a class that can never be duplicated. Correct usage is
|
18 |
thus:
|
|
19 |
|
|
1590
by Stephen Boddy
(trunk-1599/1600/1601) |
20 |
>>> from borg import Borg
|
21 |
>>> class foo(Borg):
|
|
22 |
... # All attributes on a borg class *must* = None
|
|
23 |
... attribute = None
|
|
24 |
... def __init__(self):
|
|
25 |
... Borg.__init__(self, self.__class__.__name__)
|
|
26 |
... def prepare_attributes(self):
|
|
27 |
... if not self.attribute:
|
|
28 |
... self.attribute = []
|
|
29 |
...
|
|
30 |
>>> bar = foo()
|
|
31 |
>>> bar.prepare_attributes()
|
|
775.1.92
by Chris Jones
Flesh out the borg a little |
32 |
|
33 |
The important thing to note is that all attributes of borg classes *must* be
|
|
34 |
declared as being None. If you attempt to use static class attributes you
|
|
35 |
will get unpredicted behaviour. Instead, prepare_attributes() must be called
|
|
36 |
which will then see the attributes in the shared state, and initialise them
|
|
37 |
if necessary."""
|
|
775.1.20
by Chris Jones
switch from a singleton to a borg, and don't do circular imports |
38 |
__shared_state = {} |
775.1.92
by Chris Jones
Flesh out the borg a little |
39 |
|
775.1.189
by Chris Jones
extend test coverage to ensure borg state is unique between borg types. add some debugging info and support the ability to have multiple borg classes via an ugly parameter to __init__() |
40 |
def __init__(self, borgtype=None): |
775.1.92
by Chris Jones
Flesh out the borg a little |
41 |
"""Class initialiser. Overwrite our class dictionary with the shared
|
42 |
state. This makes us identical to every other instance of this class
|
|
43 |
type."""
|
|
775.1.189
by Chris Jones
extend test coverage to ensure borg state is unique between borg types. add some debugging info and support the ability to have multiple borg classes via an ugly parameter to __init__() |
44 |
if borgtype is None: |
45 |
raise TypeError('Borg::__init__: You must pass a borgtype') |
|
46 |
if not self.__shared_state.has_key(borgtype): |
|
47 |
dbg('Borg::__init__: Preparing borg state for %s' % borgtype) |
|
48 |
self.__shared_state[borgtype] = {} |
|
49 |
self.__dict__ = self.__shared_state[borgtype] |
|
775.1.20
by Chris Jones
switch from a singleton to a borg, and don't do circular imports |
50 |
|
775.1.92
by Chris Jones
Flesh out the borg a little |
51 |
def prepare_attributes(self): |
52 |
"""This should be used to prepare any attributes of the borg class."""
|
|
53 |
raise NotImplementedError('prepare_attributes') |
|
54 |