~ubuntu-branches/ubuntu/saucy/beaker/saucy

« back to all changes in this revision

Viewing changes to beaker/util.py

  • Committer: Bazaar Package Importer
  • Author(s): Piotr Ożarowski
  • Date: 2010-03-03 00:37:43 UTC
  • mfrom: (1.1.16 upstream) (2.1.18 sid)
  • Revision ID: james.westby@ubuntu.com-20100303003743-ydl9a2st185leauo
Tags: 1.5.3-1
New upstream release

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
"""Beaker utilities"""
 
2
 
2
3
try:
3
4
    import thread as _thread
4
5
    import threading as _threading
12
13
import types
13
14
import weakref
14
15
import warnings
15
 
 
16
 
try:
17
 
    Set = set
18
 
except NameError:
19
 
    from sets import Set
20
 
try:
21
 
    from hashlib import sha1
22
 
except ImportError:
23
 
    from sha import sha as sha1
 
16
import sys
 
17
 
 
18
py3k = getattr(sys, 'py3kwarning', False) or sys.version_info >= (3, 0)
 
19
py24 = sys.version_info < (2,5)
 
20
jython = sys.platform.startswith('java')
 
21
 
 
22
if py3k or jython:
 
23
    import pickle
 
24
else:
 
25
    import cPickle as pickle
24
26
 
25
27
from beaker.converters import asbool
26
 
 
27
 
try:
28
 
    from base64 import b64encode, b64decode
29
 
except ImportError:
30
 
    import binascii
31
 
 
32
 
    _translation = [chr(_x) for _x in range(256)]
33
 
 
34
 
    # From Python 2.5 base64.py
35
 
    def _translate(s, altchars):
36
 
        translation = _translation[:]
37
 
        for k, v in altchars.items():
38
 
            translation[ord(k)] = v
39
 
        return s.translate(''.join(translation))
40
 
 
41
 
    def b64encode(s, altchars=None):
42
 
        """Encode a string using Base64.
43
 
 
44
 
        s is the string to encode.  Optional altchars must be a string of at least
45
 
        length 2 (additional characters are ignored) which specifies an
46
 
        alternative alphabet for the '+' and '/' characters.  This allows an
47
 
        application to e.g. generate url or filesystem safe Base64 strings.
48
 
 
49
 
        The encoded string is returned.
50
 
        """
51
 
        # Strip off the trailing newline
52
 
        encoded = binascii.b2a_base64(s)[:-1]
53
 
        if altchars is not None:
54
 
            return _translate(encoded, {'+': altchars[0], '/': altchars[1]})
55
 
        return encoded
56
 
 
57
 
    def b64decode(s, altchars=None):
58
 
        """Decode a Base64 encoded string.
59
 
 
60
 
        s is the string to decode.  Optional altchars must be a string of at least
61
 
        length 2 (additional characters are ignored) which specifies the
62
 
        alternative alphabet used instead of the '+' and '/' characters.
63
 
 
64
 
        The decoded string is returned.  A TypeError is raised if s were
65
 
        incorrectly padded or if there are non-alphabet characters present in the
66
 
        string.
67
 
        """
68
 
        if altchars is not None:
69
 
            s = _translate(s, {altchars[0]: '+', altchars[1]: '/'})
70
 
        try:
71
 
            return binascii.a2b_base64(s)
72
 
        except binascii.Error, msg:
73
 
            # Transform this exception for consistency
74
 
            raise TypeError(msg)
75
 
 
76
 
try:
77
 
    from threading import local as _tlocal
78
 
except ImportError:
79
 
    try:
80
 
        from dummy_threading import local as _tlocal
81
 
    except ImportError:
82
 
        class _tlocal(object):
83
 
            def __init__(self):
84
 
                self.__dict__['_tdict'] = {}
85
 
 
86
 
            def __delattr__(self, key):
87
 
                try:
88
 
                    del self._tdict[(thread.get_ident(), key)]
89
 
                except KeyError:
90
 
                    raise AttributeError(key)
91
 
 
92
 
            def __getattr__(self, key):
93
 
                try:
94
 
                    return self._tdict[(thread.get_ident(), key)]
95
 
                except KeyError:
96
 
                    raise AttributeError(key)
97
 
 
98
 
            def __setattr__(self, key, value):
99
 
                self._tdict[(thread.get_ident(), key)] = value
 
28
from threading import local as _tlocal
100
29
 
101
30
 
102
31
__all__  = ["ThreadLocal", "Registry", "WeakValuedRegistry", "SyncDict",
117
46
                raise
118
47
 
119
48
    
120
 
def deprecated(func, message):
121
 
    def deprecated_method(*args, **kargs):
122
 
        warnings.warn(message, DeprecationWarning, 2)
123
 
        return func(*args, **kargs)
124
 
    try:
125
 
        deprecated_method.__name__ = func.__name__
126
 
    except TypeError: # Python < 2.4
127
 
        pass
128
 
    deprecated_method.__doc__ = "%s\n\n%s" % (message, func.__doc__)
129
 
    return deprecated_method
130
 
 
 
49
def deprecated(message):
 
50
    def wrapper(fn):
 
51
        def deprecated_method(*args, **kargs):
 
52
            warnings.warn(message, DeprecationWarning, 2)
 
53
            return fn(*args, **kargs)
 
54
        # TODO: use decorator ?  functools.wrapper ?
 
55
        deprecated_method.__name__ = fn.__name__
 
56
        deprecated_method.__doc__ = "%s\n\n%s" % (message, fn.__doc__)
 
57
        return deprecated_method
 
58
    return wrapper
 
59
    
131
60
class ThreadLocal(object):
132
61
    """stores a value on a per-thread basis"""
133
62
 
214
143
        self.mutex = _threading.RLock()
215
144
        self.dict = weakref.WeakValueDictionary()
216
145
 
217
 
            
 
146
sha1 = None            
218
147
def encoded_path(root, identifiers, extension = ".enc", depth = 3,
219
148
                 digest_filenames=True):
 
149
                 
220
150
    """Generate a unique file-accessible path from the given list of
221
151
    identifiers starting at the given root directory."""
222
 
    ident = string.join(identifiers, "_")
223
 
 
 
152
    ident = "_".join(identifiers)
 
153
    
 
154
    global sha1
 
155
    if sha1 is None:
 
156
        from beaker.crypto import sha1
 
157
        
224
158
    if digest_filenames:
225
 
        ident = sha1(ident).hexdigest()
 
159
        if py3k:
 
160
            ident = sha1(ident.encode('utf-8')).hexdigest()
 
161
        else:
 
162
            ident = sha1(ident).hexdigest()
226
163
    
227
164
    ident = os.path.basename(ident)
228
165
 
272
209
    rules = [
273
210
        ('data_dir', (str, types.NoneType), "data_dir must be a string "
274
211
         "referring to a directory."),
275
 
        ('lock_dir', (str,), "lock_dir must be a string referring to a "
 
212
        ('lock_dir', (str, types.NoneType), "lock_dir must be a string referring to a "
276
213
         "directory."),
277
214
        ('type', (str, types.NoneType), "Session type must be a string."),
278
215
        ('cookie_expires', (bool, datetime, timedelta), "Cookie expires was "
298
235
    rules = [
299
236
        ('data_dir', (str, types.NoneType), "data_dir must be a string "
300
237
         "referring to a directory."),
301
 
        ('lock_dir', (str,), "lock_dir must be a string referring to a "
 
238
        ('lock_dir', (str, types.NoneType), "lock_dir must be a string referring to a "
302
239
         "directory."),
303
240
        ('type', (str,), "Cache type must be a string."),
304
241
        ('enabled', (bool, types.NoneType), "enabled must be true/false "
314
251
def parse_cache_config_options(config, include_defaults=True):
315
252
    """Parse configuration options and validate for use with the
316
253
    CacheManager"""
 
254
    
317
255
    # Load default cache options
318
256
    if include_defaults:
319
257
        options= dict(type='memory', data_dir=None, expire=None,