root/galaxy-central/eggs/Babel-0.9.4-py2.6.egg/babel/localedata.py @ 3

リビジョン 3, 6.4 KB (コミッタ: kohda, 14 年 前)

Install Unix tools  http://hannonlab.cshl.edu/galaxy_unix_tools/galaxy.html

行番号 
1# -*- coding: utf-8 -*-
2#
3# Copyright (C) 2007 Edgewall Software
4# All rights reserved.
5#
6# This software is licensed as described in the file COPYING, which
7# you should have received as part of this distribution. The terms
8# are also available at http://babel.edgewall.org/wiki/License.
9#
10# This software consists of voluntary contributions made by many
11# individuals. For the exact contribution history, see the revision
12# history and logs, available at http://babel.edgewall.org/log/.
13
14"""Low-level locale data access.
15
16:note: The `Locale` class, which uses this module under the hood, provides a
17       more convenient interface for accessing the locale data.
18"""
19
20import os
21import pickle
22try:
23    import threading
24except ImportError:
25    import dummy_threading as threading
26from UserDict import DictMixin
27
28__all__ = ['exists', 'list', 'load']
29__docformat__ = 'restructuredtext en'
30
31_cache = {}
32_cache_lock = threading.RLock()
33_dirname = os.path.join(os.path.dirname(__file__), 'localedata')
34
35
36def exists(name):
37    """Check whether locale data is available for the given locale.
38   
39    :param name: the locale identifier string
40    :return: `True` if the locale data exists, `False` otherwise
41    :rtype: `bool`
42    """
43    if name in _cache:
44        return True
45    return os.path.exists(os.path.join(_dirname, '%s.dat' % name))
46
47
48def list():
49    """Return a list of all locale identifiers for which locale data is
50    available.
51   
52    :return: a list of locale identifiers (strings)
53    :rtype: `list`
54    :since: version 0.8.1
55    """
56    return [stem for stem, extension in [
57        os.path.splitext(filename) for filename in os.listdir(_dirname)
58    ] if extension == '.dat' and stem != 'root']
59
60
61def load(name, merge_inherited=True):
62    """Load the locale data for the given locale.
63   
64    The locale data is a dictionary that contains much of the data defined by
65    the Common Locale Data Repository (CLDR). This data is stored as a
66    collection of pickle files inside the ``babel`` package.
67   
68    >>> d = load('en_US')
69    >>> d['languages']['sv']
70    u'Swedish'
71   
72    Note that the results are cached, and subsequent requests for the same
73    locale return the same dictionary:
74   
75    >>> d1 = load('en_US')
76    >>> d2 = load('en_US')
77    >>> d1 is d2
78    True
79   
80    :param name: the locale identifier string (or "root")
81    :param merge_inherited: whether the inherited data should be merged into
82                            the data of the requested locale
83    :return: the locale data
84    :rtype: `dict`
85    :raise `IOError`: if no locale data file is found for the given locale
86                      identifer, or one of the locales it inherits from
87    """
88    _cache_lock.acquire()
89    try:
90        data = _cache.get(name)
91        if not data:
92            # Load inherited data
93            if name == 'root' or not merge_inherited:
94                data = {}
95            else:
96                parts = name.split('_')
97                if len(parts) == 1:
98                    parent = 'root'
99                else:
100                    parent = '_'.join(parts[:-1])
101                data = load(parent).copy()
102            filename = os.path.join(_dirname, '%s.dat' % name)
103            fileobj = open(filename, 'rb')
104            try:
105                if name != 'root' and merge_inherited:
106                    merge(data, pickle.load(fileobj))
107                else:
108                    data = pickle.load(fileobj)
109                _cache[name] = data
110            finally:
111                fileobj.close()
112        return data
113    finally:
114        _cache_lock.release()
115
116
117def merge(dict1, dict2):
118    """Merge the data from `dict2` into the `dict1` dictionary, making copies
119    of nested dictionaries.
120   
121    >>> d = {1: 'foo', 3: 'baz'}
122    >>> merge(d, {1: 'Foo', 2: 'Bar'})
123    >>> d
124    {1: 'Foo', 2: 'Bar', 3: 'baz'}
125   
126    :param dict1: the dictionary to merge into
127    :param dict2: the dictionary containing the data that should be merged
128    """
129    for key, val2 in dict2.items():
130        if val2 is not None:
131            val1 = dict1.get(key)
132            if isinstance(val2, dict):
133                if val1 is None:
134                    val1 = {}
135                if isinstance(val1, Alias):
136                    val1 = (val1, val2)
137                elif isinstance(val1, tuple):
138                    alias, others = val1
139                    others = others.copy()
140                    merge(others, val2)
141                    val1 = (alias, others)
142                else:
143                    val1 = val1.copy()
144                    merge(val1, val2)
145            else:
146                val1 = val2
147            dict1[key] = val1
148
149
150class Alias(object):
151    """Representation of an alias in the locale data.
152   
153    An alias is a value that refers to some other part of the locale data,
154    as specified by the `keys`.
155    """
156
157    def __init__(self, keys):
158        self.keys = tuple(keys)
159
160    def __repr__(self):
161        return '<%s %r>' % (type(self).__name__, self.keys)
162
163    def resolve(self, data):
164        """Resolve the alias based on the given data.
165       
166        This is done recursively, so if one alias resolves to a second alias,
167        that second alias will also be resolved.
168       
169        :param data: the locale data
170        :type data: `dict`
171        """
172        base = data
173        for key in self.keys:
174            data = data[key]
175        if isinstance(data, Alias):
176            data = data.resolve(base)
177        elif isinstance(data, tuple):
178            alias, others = data
179            data = alias.resolve(base)
180        return data
181
182
183class LocaleDataDict(DictMixin, dict):
184    """Dictionary wrapper that automatically resolves aliases to the actual
185    values.
186    """
187
188    def __init__(self, data, base=None):
189        dict.__init__(self, data)
190        if base is None:
191            base = data
192        self.base = base
193
194    def __getitem__(self, key):
195        orig = val = dict.__getitem__(self, key)
196        if isinstance(val, Alias): # resolve an alias
197            val = val.resolve(self.base)
198        if isinstance(val, tuple): # Merge a partial dict with an alias
199            alias, others = val
200            val = alias.resolve(self.base).copy()
201            merge(val, others)
202        if type(val) is dict: # Return a nested alias-resolving dict
203            val = LocaleDataDict(val, base=self.base)
204        if val is not orig:
205            self[key] = val
206        return val
207
208    def copy(self):
209        return LocaleDataDict(dict.copy(self), base=self.base)
Note: リポジトリブラウザについてのヘルプは TracBrowser を参照してください。