Mercurial > babel > old > babel-test
annotate babel/messages/catalog.py @ 64:0406c51c5463
`read_po` now returns a `Catalog`.
author | cmlenz |
---|---|
date | Fri, 08 Jun 2007 13:15:32 +0000 |
parents | da7efa40a9e2 |
children | 5496b9127a07 |
rev | line source |
---|---|
56
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
1 # -*- coding: utf-8 -*- |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
2 # |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
3 # Copyright (C) 2007 Edgewall Software |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
4 # All rights reserved. |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
5 # |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
6 # This software is licensed as described in the file COPYING, which |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
7 # you should have received as part of this distribution. The terms |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
8 # are also available at http://babel.edgewall.org/wiki/License. |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
9 # |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
10 # This software consists of voluntary contributions made by many |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
11 # individuals. For the exact contribution history, see the revision |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
12 # history and logs, available at http://babel.edgewall.org/log/. |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
13 |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
14 """Data structures for message catalogs.""" |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
15 |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
16 import re |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
17 try: |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
18 set |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
19 except NameError: |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
20 from sets import Set as set |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
21 |
64 | 22 from babel.core import Locale |
56
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
23 from babel.util import odict |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
24 |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
25 __all__ = ['Message', 'Catalog'] |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
26 __docformat__ = 'restructuredtext en' |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
27 |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
28 PYTHON_FORMAT = re.compile(r'\%(\([\w]+\))?[diouxXeEfFgGcrs]').search |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
29 |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
30 |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
31 class Message(object): |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
32 """Representation of a single message in a catalog.""" |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
33 |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
34 def __init__(self, id, string=None, locations=(), flags=()): |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
35 """Create the message object. |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
36 |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
37 :param id: the message ID, or a ``(singular, plural)`` tuple for |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
38 pluralizable messages |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
39 :param string: the translated message string, or a |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
40 ``(singular, plural)`` tuple for pluralizable messages |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
41 :param locations: a sequence of ``(filenname, lineno)`` tuples |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
42 :param flags: a set or sequence of flags |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
43 """ |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
44 self.id = id |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
45 self.string = string |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
46 self.locations = locations |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
47 self.flags = set(flags) |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
48 if self.python_format: |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
49 self.flags.add('python-format') |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
50 else: |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
51 self.flags.discard('python-format') |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
52 |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
53 def __repr__(self): |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
54 return '<%s %r>' % (type(self).__name__, self.id) |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
55 |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
56 def pluralizable(self): |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
57 return isinstance(self.id, (list, tuple)) |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
58 pluralizable = property(pluralizable, doc="""\ |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
59 Whether the message is plurizable. |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
60 |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
61 >>> Message('foo').pluralizable |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
62 False |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
63 >>> Message(('foo', 'bar')).pluralizable |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
64 True |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
65 |
61
da7efa40a9e2
Move `Translations` and `LazyProxy` to new `babel.support` module, which should contain any convenience code that is useful for applications using Babel/I18n, but not used by Babel itself.
cmlenz
parents:
56
diff
changeset
|
66 :type: `bool` |
56
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
67 """) |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
68 |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
69 def python_format(self): |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
70 ids = self.id |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
71 if not isinstance(ids, (list, tuple)): |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
72 ids = [ids] |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
73 return bool(filter(None, [PYTHON_FORMAT(id) for id in ids])) |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
74 python_format = property(python_format, doc="""\ |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
75 Whether the message contains Python-style parameters. |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
76 |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
77 >>> Message('foo %(name)s bar').python_format |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
78 True |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
79 >>> Message(('foo %(name)s', 'foo %(name)s')).python_format |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
80 True |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
81 |
61
da7efa40a9e2
Move `Translations` and `LazyProxy` to new `babel.support` module, which should contain any convenience code that is useful for applications using Babel/I18n, but not used by Babel itself.
cmlenz
parents:
56
diff
changeset
|
82 :type: `bool` |
56
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
83 """) |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
84 |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
85 |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
86 class Catalog(object): |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
87 """Representation a message catalog.""" |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
88 |
64 | 89 def __init__(self, domain=None, locale=None): |
90 """Initialize the catalog object. | |
91 | |
92 :param domain: the message domain | |
93 :param locale: the locale identifier or `Locale` object, or `None` | |
94 if the catalog is not bound to a locale (which basically | |
95 means it's a template) | |
96 """ | |
97 self.domain = domain #: the message domain | |
98 if locale: | |
99 locale = Locale.parse(locale) | |
100 self.locale = locale #: the locale or `None` | |
101 self.messages = odict() #: the actual `Message` entries by ID | |
56
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
102 |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
103 def __iter__(self): |
64 | 104 """Iterates through all the entries in the catalog, in the order they |
105 were added, yielding a `Message` object for every entry. | |
106 | |
107 :rtype: ``iterator`` | |
108 """ | |
56
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
109 for id in self.messages: |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
110 yield self.messages[id] |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
111 |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
112 def __repr__(self): |
64 | 113 locale = '' |
114 if self.locale: | |
115 locale = ' %s' % self.locale | |
116 return '<%s %r%s>' % (type(self).__name__, self.domain, locale) | |
56
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
117 |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
118 def __delitem__(self, id): |
64 | 119 """Delete the message with the specified ID.""" |
56
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
120 if id in self.messaages: |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
121 del self.messages[id] |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
122 |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
123 def __getitem__(self, id): |
64 | 124 """Return the message with the specified ID. |
125 | |
126 :param id: the message ID | |
127 :return: the message with the specified ID, or `None` if no such message | |
128 is in the catalog | |
129 :rytpe: `Message` | |
130 """ | |
56
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
131 return self.messages.get(id) |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
132 |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
133 def __setitem__(self, id, message): |
64 | 134 """Add or update the message with the specified ID. |
135 | |
136 >>> catalog = Catalog() | |
137 >>> catalog[u'foo'] = Message(u'foo') | |
138 >>> catalog[u'foo'] | |
139 <Message u'foo'> | |
140 | |
141 If a message with that ID is already in the catalog, it is updated | |
142 to include the locations and flags of the new message. | |
143 | |
144 >>> catalog = Catalog() | |
145 >>> catalog[u'foo'] = Message(u'foo', locations=[('main.py', 1)]) | |
146 >>> catalog[u'foo'].locations | |
147 [('main.py', 1)] | |
148 >>> catalog[u'foo'] = Message(u'foo', locations=[('utils.py', 5)]) | |
149 >>> catalog[u'foo'].locations | |
150 [('main.py', 1), ('utils.py', 5)] | |
151 | |
152 :param id: the message ID | |
153 :param message: the `Message` object | |
154 """ | |
56
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
155 assert isinstance(message, Message), 'expected a Message object' |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
156 current = self.messages.get(id) |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
157 if current: |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
158 assert current.string == message.string, 'translation mismatch' |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
159 current.locations.extend(message.locations) |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
160 current.flags |= message.flags |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
161 message = current |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
162 else: |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
163 if isinstance(id, (list, tuple)): |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
164 singular, plural = id |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
165 id = singular |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
166 self.messages[id] = message |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
167 |
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
168 def add(self, id, string=None, locations=(), flags=()): |
64 | 169 """Add or update the message with the specified ID. |
170 | |
171 >>> catalog = Catalog() | |
172 >>> catalog.add(u'foo') | |
173 >>> catalog[u'foo'] | |
174 <Message u'foo'> | |
175 | |
176 This method simply constructs a `Message` object with the given | |
177 arguments and invokes `__setitem__` with that object. | |
178 | |
179 :param id: the message ID, or a ``(singular, plural)`` tuple for | |
180 pluralizable messages | |
181 :param string: the translated message string, or a | |
182 ``(singular, plural)`` tuple for pluralizable messages | |
183 :param locations: a sequence of ``(filenname, lineno)`` tuples | |
184 :param flags: a set or sequence of flags | |
185 """ | |
56
27fba894d3ca
Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents:
diff
changeset
|
186 self[id] = Message(id, string, locations, flags) |