~waldner/terminator/plugin-ng

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