/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
4763.2.4 by John Arbash Meinel
merge bzr.2.1 in preparation for NEWS entry.
1
# Copyright (C) 2006-2010 Canonical Ltd
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
2
#
1185.70.3 by Martin Pool
Various updates to make storage branch mergeable:
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
7
#
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
12
#
1185.70.3 by Martin Pool
Various updates to make storage branch mergeable:
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
4183.7.1 by Sabin Iacob
update FSF mailing address
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
1185.70.3 by Martin Pool
Various updates to make storage branch mergeable:
16
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
17
from . import trace
4634.85.9 by Andrew Bennetts
Add some experimental decorators: @only_raises(..) and @cleanup_method.
18
3316.3.1 by Andrew Bennetts
Try not to lose the original exception in needs_write_lock decorator if the unlock raises a secondary exception.
19
4634.85.9 by Andrew Bennetts
Add some experimental decorators: @only_raises(..) and @cleanup_method.
20
def only_raises(*errors):
4634.62.2 by Andrew Bennetts
Update test_decorators, add docstring.
21
    """Make a decorator that will only allow the given error classes to be
22
    raised.  All other errors will be logged and then discarded.
23
24
    Typical use is something like::
25
26
        @only_raises(LockNotHeld, LockBroken)
27
        def unlock(self):
28
            # etc
29
    """
4634.85.9 by Andrew Bennetts
Add some experimental decorators: @only_raises(..) and @cleanup_method.
30
    def decorator(unbound):
31
        def wrapped(*args, **kwargs):
32
            try:
33
                return unbound(*args, **kwargs)
34
            except errors:
35
                raise
36
            except:
37
                trace.mutter('Error suppressed by only_raises:')
38
                trace.log_exception_quietly()
39
        wrapped.__doc__ = unbound.__doc__
40
        wrapped.__name__ = unbound.__name__
41
        return wrapped
42
    return decorator
43
44
4869.3.32 by Andrew Bennetts
Use Launchpad's cachedproperty decorator instead of my stupidly broken one.
45
# This implementation of cachedproperty is copied from Launchpad's
4869.3.34 by Vincent Ladeuil
Finish the patch based on reviews.
46
# canonical.launchpad.cachedproperty module (with permission from flacoste)
47
# -- spiv & vila 100120
4869.3.32 by Andrew Bennetts
Use Launchpad's cachedproperty decorator instead of my stupidly broken one.
48
def cachedproperty(attrname_or_fn):
49
    """A decorator for methods that makes them properties with their return
50
    value cached.
51
52
    The value is cached on the instance, using the attribute name provided.
53
54
    If you don't provide a name, the mangled name of the property is used.
55
56
    >>> class CachedPropertyTest(object):
57
    ...
58
    ...     @cachedproperty('_foo_cache')
59
    ...     def foo(self):
7045.4.10 by Jelmer Vernooij
Fix a couple more tests.
60
    ...         print('foo computed')
4869.3.32 by Andrew Bennetts
Use Launchpad's cachedproperty decorator instead of my stupidly broken one.
61
    ...         return 23
62
    ...
63
    ...     @cachedproperty
64
    ...     def bar(self):
7045.4.10 by Jelmer Vernooij
Fix a couple more tests.
65
    ...         print('bar computed')
4869.3.32 by Andrew Bennetts
Use Launchpad's cachedproperty decorator instead of my stupidly broken one.
66
    ...         return 69
67
68
    >>> cpt = CachedPropertyTest()
69
    >>> getattr(cpt, '_foo_cache', None) is None
70
    True
71
    >>> cpt.foo
72
    foo computed
73
    23
74
    >>> cpt.foo
75
    23
76
    >>> cpt._foo_cache
77
    23
78
    >>> cpt.bar
79
    bar computed
80
    69
81
    >>> cpt._bar_cached_value
82
    69
83
4869.3.13 by Andrew Bennetts
Add simple cachedproperty decorator, and add {this,other,base}_lines cachedproperties to MergeHookParams.
84
    """
6621.2.26 by Martin
Misc set of changes to get started with selftest on Python 3
85
    if isinstance(attrname_or_fn, str):
4869.3.32 by Andrew Bennetts
Use Launchpad's cachedproperty decorator instead of my stupidly broken one.
86
        attrname = attrname_or_fn
87
        return _CachedPropertyForAttr(attrname)
88
    else:
89
        fn = attrname_or_fn
90
        attrname = '_%s_cached_value' % fn.__name__
91
        return _CachedProperty(attrname, fn)
92
93
94
class _CachedPropertyForAttr(object):
95
96
    def __init__(self, attrname):
97
        self.attrname = attrname
98
99
    def __call__(self, fn):
100
        return _CachedProperty(self.attrname, fn)
101
102
103
class _CachedProperty(object):
104
105
    def __init__(self, attrname, fn):
106
        self.fn = fn
107
        self.attrname = attrname
108
        self.marker = object()
109
110
    def __get__(self, inst, cls=None):
111
        if inst is None:
112
            return self
113
        cachedresult = getattr(inst, self.attrname, self.marker)
114
        if cachedresult is self.marker:
115
            result = self.fn(inst)
116
            setattr(inst, self.attrname, result)
117
            return result
118
        else:
119
            return cachedresult