Statistics
| Branch: | Tag: | Revision:

root / snf-common / synnefo / lib / singleton / __init__.py @ 19092a69

History | View | Annotate | Download (2.5 kB)

1
# Copyright 2011-2012 GRNET S.A. All rights reserved.
2
#
3
# Redistribution and use in source and binary forms, with or
4
# without modification, are permitted provided that the following
5
# conditions are met:
6
#
7
#   1. Redistributions of source code must retain the above
8
#      copyright notice, this list of conditions and the following
9
#      disclaimer.
10
#
11
#   2. Redistributions in binary form must reproduce the above
12
#      copyright notice, this list of conditions and the following
13
#      disclaimer in the documentation and/or other materials
14
#      provided with the distribution.
15
#
16
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
# POSSIBILITY OF SUCH DAMAGE.
28
#
29
# The views and conclusions contained in the software and
30
# documentation are those of the authors and should not be
31
# interpreted as representing official policies, either expressed
32
# or implied, of GRNET S.A.
33

    
34

    
35
class ArgBasedSingletonMeta(type):
36
    """Implement the Singleton pattern with a twist.
37

38
    Implement the Singleton pattern with a twist:
39
    The uniqueness on the object is based on the class name,
40
    plus the argument list (args and kwargs).
41

42
    Unique objects are store in the '_singles' class attribute.
43
    A distinct _singles object is used per subclass.
44

45
    """
46
    def __call__(cls, *args, **kwargs):
47
        kwlist = str([(k, kwargs[k]) for k in sorted(kwargs.keys())])
48
        distinct = str((cls, args, kwlist))
49

    
50
        # Allocate a new _singles attribute per subclass
51
        if not hasattr(cls, "_singles_cls") or cls != cls._singles_cls:
52
            cls._singles = {}
53
            cls._singles_cls = cls
54

    
55
        if distinct not in cls._singles:
56
            obj = super(ArgBasedSingletonMeta, cls).__call__(*args, **kwargs)
57
            cls._singles[distinct] = obj
58

    
59
        ret = cls._singles[distinct]
60

    
61
        return ret
62
        
63

    
64
class ArgBasedSingleton(object):
65
    __metaclass__ = ArgBasedSingletonMeta