Statistics
| Branch: | Tag: | Revision:

root / snf-common / synnefo / lib / singleton / __init__.py @ 5f6ad491

History | View | Annotate | Download (2.5 kB)

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

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

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

45 19092a69 Vangelis Koukis
    """
46 19092a69 Vangelis Koukis
    def __call__(cls, *args, **kwargs):
47 19092a69 Vangelis Koukis
        kwlist = str([(k, kwargs[k]) for k in sorted(kwargs.keys())])
48 19092a69 Vangelis Koukis
        distinct = str((cls, args, kwlist))
49 19092a69 Vangelis Koukis
50 19092a69 Vangelis Koukis
        # Allocate a new _singles attribute per subclass
51 19092a69 Vangelis Koukis
        if not hasattr(cls, "_singles_cls") or cls != cls._singles_cls:
52 19092a69 Vangelis Koukis
            cls._singles = {}
53 19092a69 Vangelis Koukis
            cls._singles_cls = cls
54 19092a69 Vangelis Koukis
55 19092a69 Vangelis Koukis
        if distinct not in cls._singles:
56 19092a69 Vangelis Koukis
            obj = super(ArgBasedSingletonMeta, cls).__call__(*args, **kwargs)
57 19092a69 Vangelis Koukis
            cls._singles[distinct] = obj
58 19092a69 Vangelis Koukis
59 19092a69 Vangelis Koukis
        ret = cls._singles[distinct]
60 19092a69 Vangelis Koukis
61 19092a69 Vangelis Koukis
        return ret
62 19092a69 Vangelis Koukis
        
63 19092a69 Vangelis Koukis
64 19092a69 Vangelis Koukis
class ArgBasedSingleton(object):
65 19092a69 Vangelis Koukis
    __metaclass__ = ArgBasedSingletonMeta