root/masterdriverz/snakeoil/snakeoil/klass.py @ masterdriverz%2540gentoo.org-20070316195713-evqx0kx7szx3ben5

Revision masterdriverz%2540gentoo.org-20070316195713-evqx0kx7szx3ben5, 2.7 kB (checked in by Charlie Shepherd <masterdriverz@…>, 22 months ago)

Pull from pkgcore

Line 
1# Copyright: 2006 Brian Harring <ferringb@gmail.com>
2# License: GPL2
3
4from operator import attrgetter
5from snakeoil.caching import WeakInstMeta
6from collections import deque
7
8def native_GetAttrProxy(target):
9    def reflected_getattr(self, attr):
10        return getattr(getattr(self, target), attr)
11    return reflected_getattr
12
13def native_contains(self, key):
14    try:
15        self[key]
16        return True
17    except KeyError:
18        return False
19
20def native_get(self, key, default=None):
21    try:
22        return self[key]
23    except KeyError:
24        return default
25
26
27attrlist_getter = attrgetter("__attr_comparison__")
28def native_generic_eq(inst1, inst2, sentinel=object()):
29    if inst1 is inst2:
30        return True
31    for attr in attrlist_getter(inst1):
32        if getattr(inst1, attr, sentinel) != \
33            getattr(inst2, attr, sentinel):
34            return False
35    return True
36
37def native_generic_ne(inst1, inst2, sentinel=object()):
38    if inst1 is inst2:
39        return False
40    for attr in attrlist_getter(inst1):
41        if getattr(inst1, attr, sentinel) != \
42            getattr(inst2, attr, sentinel):
43            return True
44    return False
45
46try:
47    from snakeoil._klass import (GetAttrProxy, contains, get,
48        generic_eq, generic_ne)
49except ImportError:
50    GetAttrProxy = native_GetAttrProxy
51    contains = native_contains
52    get = native_get
53    generic_eq = native_generic_eq
54    generic_ne = native_generic_ne
55
56
57def generic_equality(name, bases, scope, real_type=type,
58    eq=generic_eq, ne=generic_ne):
59    attrlist = scope.pop("__attr_comparison__", None)
60    if attrlist is None:
61        raise TypeError("__attr_comparison__ must be in the classes scope")
62    for x in attrlist:
63        if not isinstance(x, str):
64            raise TypeError("all members of attrlist must be strings- "
65                " got %r %s" % (type(x), repr(x)))
66
67    scope["__attr_comparison__"] = tuple(attrlist)
68    scope.setdefault("__eq__", eq)
69    scope.setdefault("__ne__", ne)
70    return real_type(name, bases, scope)
71
72
73class chained_getter(object):
74    def __metaclass__(name, bases, scope):
75        return generic_equality(name, bases, scope, real_type=WeakInstMeta)
76    __slots__ = ('namespace', 'chain')
77    __fifo_cache__ = deque()
78    __inst_caching__ = True
79    __attr_comparison__ = ("namespace",)
80
81    def __init__(self, namespace):
82        self.namespace = namespace
83        self.chain = map(attrgetter, namespace.split("."))
84        if len(self.__fifo_cache__) > 10:
85            self.__fifo_cache__.popleft()
86        self.__fifo_cache__.append(self)
87
88    def __hash__(self):
89        return hash(self.namespace)
90
91    def __call__(self, obj):
92        o = obj
93        for f in self.chain:
94            o = f(o)
95        return o
Note: See TracBrowser for help on using the browser.