annotate babel/util.py @ 527:5e1804d27d65

Cleanup round #1: get rid of the frozenset/set utility code and imports. This is no longer needed with 2.4 and onward.
author jruigrok
date Sat, 05 Mar 2011 14:59:20 +0000
parents f03cc3bed4e1
children 5b62a9699780
rev   line source
3
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
1 # -*- coding: utf-8 -*-
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
2 #
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
3 # Copyright (C) 2007 Edgewall Software
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
4 # All rights reserved.
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
5 #
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
6 # This software is licensed as described in the file COPYING, which
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
7 # you should have received as part of this distribution. The terms
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
8 # are also available at http://babel.edgewall.org/wiki/License.
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
9 #
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
10 # This software consists of voluntary contributions made by many
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
11 # individuals. For the exact contribution history, see the revision
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
12 # history and logs, available at http://babel.edgewall.org/log/.
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
13
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
14 """Various utility classes and functions."""
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
15
166
0eccbe635dba made the python extractor detect source file encodings from the magic encoding
pjenvey
parents: 165
diff changeset
16 import codecs
32
4527f5a6ed33 Add missing import.
cmlenz
parents: 31
diff changeset
17 from datetime import timedelta, tzinfo
3
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
18 import os
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
19 import re
317
b997f09256c9 Fix for #79 (location lines wrapping at hyphens).
cmlenz
parents: 229
diff changeset
20 import textwrap
97
debd9ac3bb4d Fix for #11 (use local timezone in timestamps of generated POT).
cmlenz
parents: 64
diff changeset
21 import time
339
6811369cb912 Fix iterkeys/iteritems/itervalues/pop/popitem methods on the `odict` utility class. Thanks to Armin Ronacher for the patch.
cmlenz
parents: 330
diff changeset
22 from itertools import izip, imap
416
f03cc3bed4e1 fix Python 2.3 compat: rearrange set/itemgetter/rsplit/sorted/unicode.decode
pjenvey
parents: 356
diff changeset
23 try:
f03cc3bed4e1 fix Python 2.3 compat: rearrange set/itemgetter/rsplit/sorted/unicode.decode
pjenvey
parents: 356
diff changeset
24 from operator import itemgetter
f03cc3bed4e1 fix Python 2.3 compat: rearrange set/itemgetter/rsplit/sorted/unicode.decode
pjenvey
parents: 356
diff changeset
25 except ImportError:
f03cc3bed4e1 fix Python 2.3 compat: rearrange set/itemgetter/rsplit/sorted/unicode.decode
pjenvey
parents: 356
diff changeset
26 def itemgetter(item):
f03cc3bed4e1 fix Python 2.3 compat: rearrange set/itemgetter/rsplit/sorted/unicode.decode
pjenvey
parents: 356
diff changeset
27 return lambda obj: obj[item]
f03cc3bed4e1 fix Python 2.3 compat: rearrange set/itemgetter/rsplit/sorted/unicode.decode
pjenvey
parents: 356
diff changeset
28
339
6811369cb912 Fix iterkeys/iteritems/itervalues/pop/popitem methods on the `odict` utility class. Thanks to Armin Ronacher for the patch.
cmlenz
parents: 330
diff changeset
29 missing = object()
3
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
30
317
b997f09256c9 Fix for #79 (location lines wrapping at hyphens).
cmlenz
parents: 229
diff changeset
31 __all__ = ['distinct', 'pathmatch', 'relpath', 'wraptext', 'odict', 'UTC',
b997f09256c9 Fix for #79 (location lines wrapping at hyphens).
cmlenz
parents: 229
diff changeset
32 'LOCALTZ']
3
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
33 __docformat__ = 'restructuredtext en'
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
34
353
cd8702e96f45 Added `validate_format helper function to `babel.support`.
aronacher
parents: 339
diff changeset
35
229
85340bec3a97 Fix tests broken by [233], and add new tests.
cmlenz
parents: 167
diff changeset
36 def distinct(iterable):
85340bec3a97 Fix tests broken by [233], and add new tests.
cmlenz
parents: 167
diff changeset
37 """Yield all items in an iterable collection that are distinct.
85340bec3a97 Fix tests broken by [233], and add new tests.
cmlenz
parents: 167
diff changeset
38
85340bec3a97 Fix tests broken by [233], and add new tests.
cmlenz
parents: 167
diff changeset
39 Unlike when using sets for a similar effect, the original ordering of the
85340bec3a97 Fix tests broken by [233], and add new tests.
cmlenz
parents: 167
diff changeset
40 items in the collection is preserved by this function.
85340bec3a97 Fix tests broken by [233], and add new tests.
cmlenz
parents: 167
diff changeset
41
85340bec3a97 Fix tests broken by [233], and add new tests.
cmlenz
parents: 167
diff changeset
42 >>> print list(distinct([1, 2, 1, 3, 4, 4]))
85340bec3a97 Fix tests broken by [233], and add new tests.
cmlenz
parents: 167
diff changeset
43 [1, 2, 3, 4]
85340bec3a97 Fix tests broken by [233], and add new tests.
cmlenz
parents: 167
diff changeset
44 >>> print list(distinct('foobar'))
85340bec3a97 Fix tests broken by [233], and add new tests.
cmlenz
parents: 167
diff changeset
45 ['f', 'o', 'b', 'a', 'r']
85340bec3a97 Fix tests broken by [233], and add new tests.
cmlenz
parents: 167
diff changeset
46
85340bec3a97 Fix tests broken by [233], and add new tests.
cmlenz
parents: 167
diff changeset
47 :param iterable: the iterable collection providing the data
85340bec3a97 Fix tests broken by [233], and add new tests.
cmlenz
parents: 167
diff changeset
48 :return: the distinct items in the collection
85340bec3a97 Fix tests broken by [233], and add new tests.
cmlenz
parents: 167
diff changeset
49 :rtype: ``iterator``
85340bec3a97 Fix tests broken by [233], and add new tests.
cmlenz
parents: 167
diff changeset
50 """
85340bec3a97 Fix tests broken by [233], and add new tests.
cmlenz
parents: 167
diff changeset
51 seen = set()
85340bec3a97 Fix tests broken by [233], and add new tests.
cmlenz
parents: 167
diff changeset
52 for item in iter(iterable):
85340bec3a97 Fix tests broken by [233], and add new tests.
cmlenz
parents: 167
diff changeset
53 if item not in seen:
85340bec3a97 Fix tests broken by [233], and add new tests.
cmlenz
parents: 167
diff changeset
54 yield item
85340bec3a97 Fix tests broken by [233], and add new tests.
cmlenz
parents: 167
diff changeset
55 seen.add(item)
85340bec3a97 Fix tests broken by [233], and add new tests.
cmlenz
parents: 167
diff changeset
56
166
0eccbe635dba made the python extractor detect source file encodings from the magic encoding
pjenvey
parents: 165
diff changeset
57 # Regexp to match python magic encoding line
0eccbe635dba made the python extractor detect source file encodings from the magic encoding
pjenvey
parents: 165
diff changeset
58 PYTHON_MAGIC_COMMENT_re = re.compile(
0eccbe635dba made the python extractor detect source file encodings from the magic encoding
pjenvey
parents: 165
diff changeset
59 r'[ \t\f]* \# .* coding[=:][ \t]*([-\w.]+)', re.VERBOSE)
0eccbe635dba made the python extractor detect source file encodings from the magic encoding
pjenvey
parents: 165
diff changeset
60 def parse_encoding(fp):
0eccbe635dba made the python extractor detect source file encodings from the magic encoding
pjenvey
parents: 165
diff changeset
61 """Deduce the encoding of a source file from magic comment.
0eccbe635dba made the python extractor detect source file encodings from the magic encoding
pjenvey
parents: 165
diff changeset
62
0eccbe635dba made the python extractor detect source file encodings from the magic encoding
pjenvey
parents: 165
diff changeset
63 It does this in the same way as the `Python interpreter`__
0eccbe635dba made the python extractor detect source file encodings from the magic encoding
pjenvey
parents: 165
diff changeset
64
0eccbe635dba made the python extractor detect source file encodings from the magic encoding
pjenvey
parents: 165
diff changeset
65 .. __: http://docs.python.org/ref/encodings.html
0eccbe635dba made the python extractor detect source file encodings from the magic encoding
pjenvey
parents: 165
diff changeset
66
0eccbe635dba made the python extractor detect source file encodings from the magic encoding
pjenvey
parents: 165
diff changeset
67 The ``fp`` argument should be a seekable file object.
0eccbe635dba made the python extractor detect source file encodings from the magic encoding
pjenvey
parents: 165
diff changeset
68
0eccbe635dba made the python extractor detect source file encodings from the magic encoding
pjenvey
parents: 165
diff changeset
69 (From Jeff Dairiki)
0eccbe635dba made the python extractor detect source file encodings from the magic encoding
pjenvey
parents: 165
diff changeset
70 """
0eccbe635dba made the python extractor detect source file encodings from the magic encoding
pjenvey
parents: 165
diff changeset
71 pos = fp.tell()
0eccbe635dba made the python extractor detect source file encodings from the magic encoding
pjenvey
parents: 165
diff changeset
72 fp.seek(0)
0eccbe635dba made the python extractor detect source file encodings from the magic encoding
pjenvey
parents: 165
diff changeset
73 try:
0eccbe635dba made the python extractor detect source file encodings from the magic encoding
pjenvey
parents: 165
diff changeset
74 line1 = fp.readline()
0eccbe635dba made the python extractor detect source file encodings from the magic encoding
pjenvey
parents: 165
diff changeset
75 has_bom = line1.startswith(codecs.BOM_UTF8)
0eccbe635dba made the python extractor detect source file encodings from the magic encoding
pjenvey
parents: 165
diff changeset
76 if has_bom:
0eccbe635dba made the python extractor detect source file encodings from the magic encoding
pjenvey
parents: 165
diff changeset
77 line1 = line1[len(codecs.BOM_UTF8):]
0eccbe635dba made the python extractor detect source file encodings from the magic encoding
pjenvey
parents: 165
diff changeset
78
0eccbe635dba made the python extractor detect source file encodings from the magic encoding
pjenvey
parents: 165
diff changeset
79 m = PYTHON_MAGIC_COMMENT_re.match(line1)
0eccbe635dba made the python extractor detect source file encodings from the magic encoding
pjenvey
parents: 165
diff changeset
80 if not m:
0eccbe635dba made the python extractor detect source file encodings from the magic encoding
pjenvey
parents: 165
diff changeset
81 try:
330
9809b94b7d88 Reinstate changeset r362, but this time properly wrap the exception list in
jruigrok
parents: 329
diff changeset
82 import parser
166
0eccbe635dba made the python extractor detect source file encodings from the magic encoding
pjenvey
parents: 165
diff changeset
83 parser.suite(line1)
330
9809b94b7d88 Reinstate changeset r362, but this time properly wrap the exception list in
jruigrok
parents: 329
diff changeset
84 except (ImportError, SyntaxError):
166
0eccbe635dba made the python extractor detect source file encodings from the magic encoding
pjenvey
parents: 165
diff changeset
85 # Either it's a real syntax error, in which case the source is
0eccbe635dba made the python extractor detect source file encodings from the magic encoding
pjenvey
parents: 165
diff changeset
86 # not valid python source, or line2 is a continuation of line1,
0eccbe635dba made the python extractor detect source file encodings from the magic encoding
pjenvey
parents: 165
diff changeset
87 # in which case we don't want to scan line2 for a magic
0eccbe635dba made the python extractor detect source file encodings from the magic encoding
pjenvey
parents: 165
diff changeset
88 # comment.
0eccbe635dba made the python extractor detect source file encodings from the magic encoding
pjenvey
parents: 165
diff changeset
89 pass
0eccbe635dba made the python extractor detect source file encodings from the magic encoding
pjenvey
parents: 165
diff changeset
90 else:
0eccbe635dba made the python extractor detect source file encodings from the magic encoding
pjenvey
parents: 165
diff changeset
91 line2 = fp.readline()
0eccbe635dba made the python extractor detect source file encodings from the magic encoding
pjenvey
parents: 165
diff changeset
92 m = PYTHON_MAGIC_COMMENT_re.match(line2)
0eccbe635dba made the python extractor detect source file encodings from the magic encoding
pjenvey
parents: 165
diff changeset
93
0eccbe635dba made the python extractor detect source file encodings from the magic encoding
pjenvey
parents: 165
diff changeset
94 if has_bom:
0eccbe635dba made the python extractor detect source file encodings from the magic encoding
pjenvey
parents: 165
diff changeset
95 if m:
0eccbe635dba made the python extractor detect source file encodings from the magic encoding
pjenvey
parents: 165
diff changeset
96 raise SyntaxError(
0eccbe635dba made the python extractor detect source file encodings from the magic encoding
pjenvey
parents: 165
diff changeset
97 "python refuses to compile code with both a UTF8 "
0eccbe635dba made the python extractor detect source file encodings from the magic encoding
pjenvey
parents: 165
diff changeset
98 "byte-order-mark and a magic encoding comment")
0eccbe635dba made the python extractor detect source file encodings from the magic encoding
pjenvey
parents: 165
diff changeset
99 return 'utf_8'
0eccbe635dba made the python extractor detect source file encodings from the magic encoding
pjenvey
parents: 165
diff changeset
100 elif m:
0eccbe635dba made the python extractor detect source file encodings from the magic encoding
pjenvey
parents: 165
diff changeset
101 return m.group(1)
0eccbe635dba made the python extractor detect source file encodings from the magic encoding
pjenvey
parents: 165
diff changeset
102 else:
0eccbe635dba made the python extractor detect source file encodings from the magic encoding
pjenvey
parents: 165
diff changeset
103 return None
0eccbe635dba made the python extractor detect source file encodings from the magic encoding
pjenvey
parents: 165
diff changeset
104 finally:
0eccbe635dba made the python extractor detect source file encodings from the magic encoding
pjenvey
parents: 165
diff changeset
105 fp.seek(pos)
0eccbe635dba made the python extractor detect source file encodings from the magic encoding
pjenvey
parents: 165
diff changeset
106
46
0f140f1092e3 Some work towards #4.
cmlenz
parents: 41
diff changeset
107 def pathmatch(pattern, filename):
0f140f1092e3 Some work towards #4.
cmlenz
parents: 41
diff changeset
108 """Extended pathname pattern matching.
3
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
109
46
0f140f1092e3 Some work towards #4.
cmlenz
parents: 41
diff changeset
110 This function is similar to what is provided by the ``fnmatch`` module in
0f140f1092e3 Some work towards #4.
cmlenz
parents: 41
diff changeset
111 the Python standard library, but:
0f140f1092e3 Some work towards #4.
cmlenz
parents: 41
diff changeset
112
0f140f1092e3 Some work towards #4.
cmlenz
parents: 41
diff changeset
113 * can match complete (relative or absolute) path names, and not just file
0f140f1092e3 Some work towards #4.
cmlenz
parents: 41
diff changeset
114 names, and
0f140f1092e3 Some work towards #4.
cmlenz
parents: 41
diff changeset
115 * also supports a convenience pattern ("**") to match files at any
0f140f1092e3 Some work towards #4.
cmlenz
parents: 41
diff changeset
116 directory level.
0f140f1092e3 Some work towards #4.
cmlenz
parents: 41
diff changeset
117
0f140f1092e3 Some work towards #4.
cmlenz
parents: 41
diff changeset
118 Examples:
0f140f1092e3 Some work towards #4.
cmlenz
parents: 41
diff changeset
119
0f140f1092e3 Some work towards #4.
cmlenz
parents: 41
diff changeset
120 >>> pathmatch('**.py', 'bar.py')
0f140f1092e3 Some work towards #4.
cmlenz
parents: 41
diff changeset
121 True
0f140f1092e3 Some work towards #4.
cmlenz
parents: 41
diff changeset
122 >>> pathmatch('**.py', 'foo/bar/baz.py')
0f140f1092e3 Some work towards #4.
cmlenz
parents: 41
diff changeset
123 True
0f140f1092e3 Some work towards #4.
cmlenz
parents: 41
diff changeset
124 >>> pathmatch('**.py', 'templates/index.html')
0f140f1092e3 Some work towards #4.
cmlenz
parents: 41
diff changeset
125 False
49
9979a409589e Support passing extraction method mapping and options from the frontends (see #4). No distutils/setuptools keyword supported yet, but the rest seems to be working okay.
cmlenz
parents: 46
diff changeset
126
46
0f140f1092e3 Some work towards #4.
cmlenz
parents: 41
diff changeset
127 >>> pathmatch('**/templates/*.html', 'templates/index.html')
0f140f1092e3 Some work towards #4.
cmlenz
parents: 41
diff changeset
128 True
0f140f1092e3 Some work towards #4.
cmlenz
parents: 41
diff changeset
129 >>> pathmatch('**/templates/*.html', 'templates/foo/bar.html')
0f140f1092e3 Some work towards #4.
cmlenz
parents: 41
diff changeset
130 False
3
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
131
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
132 :param pattern: the glob pattern
46
0f140f1092e3 Some work towards #4.
cmlenz
parents: 41
diff changeset
133 :param filename: the path name of the file to match against
0f140f1092e3 Some work towards #4.
cmlenz
parents: 41
diff changeset
134 :return: `True` if the path name matches the pattern, `False` otherwise
0f140f1092e3 Some work towards #4.
cmlenz
parents: 41
diff changeset
135 :rtype: `bool`
3
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
136 """
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
137 symbols = {
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
138 '?': '[^/]',
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
139 '?/': '[^/]/',
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
140 '*': '[^/]+',
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
141 '*/': '[^/]+/',
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
142 '**/': '(?:.+/)*?',
46
0f140f1092e3 Some work towards #4.
cmlenz
parents: 41
diff changeset
143 '**': '(?:.+/)*?[^/]+',
3
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
144 }
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
145 buf = []
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
146 for idx, part in enumerate(re.split('([?*]+/?)', pattern)):
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
147 if idx % 2:
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
148 buf.append(symbols[part])
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
149 elif part:
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
150 buf.append(re.escape(part))
136
9e3d2b227ec3 More fixes for Windows compatibility:
cmlenz
parents: 132
diff changeset
151 match = re.match(''.join(buf) + '$', filename.replace(os.sep, '/'))
9e3d2b227ec3 More fixes for Windows compatibility:
cmlenz
parents: 132
diff changeset
152 return match is not None
3
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
153
31
3956bb7ff93b More work on timezones.
cmlenz
parents: 15
diff changeset
154
317
b997f09256c9 Fix for #79 (location lines wrapping at hyphens).
cmlenz
parents: 229
diff changeset
155 class TextWrapper(textwrap.TextWrapper):
b997f09256c9 Fix for #79 (location lines wrapping at hyphens).
cmlenz
parents: 229
diff changeset
156 wordsep_re = re.compile(
b997f09256c9 Fix for #79 (location lines wrapping at hyphens).
cmlenz
parents: 229
diff changeset
157 r'(\s+|' # any whitespace
b997f09256c9 Fix for #79 (location lines wrapping at hyphens).
cmlenz
parents: 229
diff changeset
158 r'(?<=[\w\!\"\'\&\.\,\?])-{2,}(?=\w))' # em-dash
b997f09256c9 Fix for #79 (location lines wrapping at hyphens).
cmlenz
parents: 229
diff changeset
159 )
b997f09256c9 Fix for #79 (location lines wrapping at hyphens).
cmlenz
parents: 229
diff changeset
160
b997f09256c9 Fix for #79 (location lines wrapping at hyphens).
cmlenz
parents: 229
diff changeset
161
b997f09256c9 Fix for #79 (location lines wrapping at hyphens).
cmlenz
parents: 229
diff changeset
162 def wraptext(text, width=70, initial_indent='', subsequent_indent=''):
b997f09256c9 Fix for #79 (location lines wrapping at hyphens).
cmlenz
parents: 229
diff changeset
163 """Simple wrapper around the ``textwrap.wrap`` function in the standard
b997f09256c9 Fix for #79 (location lines wrapping at hyphens).
cmlenz
parents: 229
diff changeset
164 library. This version does not wrap lines on hyphens in words.
b997f09256c9 Fix for #79 (location lines wrapping at hyphens).
cmlenz
parents: 229
diff changeset
165
b997f09256c9 Fix for #79 (location lines wrapping at hyphens).
cmlenz
parents: 229
diff changeset
166 :param text: the text to wrap
b997f09256c9 Fix for #79 (location lines wrapping at hyphens).
cmlenz
parents: 229
diff changeset
167 :param width: the maximum line width
b997f09256c9 Fix for #79 (location lines wrapping at hyphens).
cmlenz
parents: 229
diff changeset
168 :param initial_indent: string that will be prepended to the first line of
b997f09256c9 Fix for #79 (location lines wrapping at hyphens).
cmlenz
parents: 229
diff changeset
169 wrapped output
b997f09256c9 Fix for #79 (location lines wrapping at hyphens).
cmlenz
parents: 229
diff changeset
170 :param subsequent_indent: string that will be prepended to all lines save
b997f09256c9 Fix for #79 (location lines wrapping at hyphens).
cmlenz
parents: 229
diff changeset
171 the first of wrapped output
b997f09256c9 Fix for #79 (location lines wrapping at hyphens).
cmlenz
parents: 229
diff changeset
172 :return: a list of lines
b997f09256c9 Fix for #79 (location lines wrapping at hyphens).
cmlenz
parents: 229
diff changeset
173 :rtype: `list`
b997f09256c9 Fix for #79 (location lines wrapping at hyphens).
cmlenz
parents: 229
diff changeset
174 """
b997f09256c9 Fix for #79 (location lines wrapping at hyphens).
cmlenz
parents: 229
diff changeset
175 wrapper = TextWrapper(width=width, initial_indent=initial_indent,
b997f09256c9 Fix for #79 (location lines wrapping at hyphens).
cmlenz
parents: 229
diff changeset
176 subsequent_indent=subsequent_indent,
b997f09256c9 Fix for #79 (location lines wrapping at hyphens).
cmlenz
parents: 229
diff changeset
177 break_long_words=False)
b997f09256c9 Fix for #79 (location lines wrapping at hyphens).
cmlenz
parents: 229
diff changeset
178 return wrapper.wrap(text)
b997f09256c9 Fix for #79 (location lines wrapping at hyphens).
cmlenz
parents: 229
diff changeset
179
b997f09256c9 Fix for #79 (location lines wrapping at hyphens).
cmlenz
parents: 229
diff changeset
180
58
068952b4d4c0 Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents: 49
diff changeset
181 class odict(dict):
068952b4d4c0 Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents: 49
diff changeset
182 """Ordered dict implementation.
068952b4d4c0 Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents: 49
diff changeset
183
229
85340bec3a97 Fix tests broken by [233], and add new tests.
cmlenz
parents: 167
diff changeset
184 :see: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/107747
58
068952b4d4c0 Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents: 49
diff changeset
185 """
64
7eb6fea17864 The order of extraction methods is now preserved (see #10).
cmlenz
parents: 62
diff changeset
186 def __init__(self, data=None):
7eb6fea17864 The order of extraction methods is now preserved (see #10).
cmlenz
parents: 62
diff changeset
187 dict.__init__(self, data or {})
165
eafaa302dde1 Added preliminary catalog updating/merging functionality.
cmlenz
parents: 136
diff changeset
188 self._keys = dict.keys(self)
58
068952b4d4c0 Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents: 49
diff changeset
189
068952b4d4c0 Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents: 49
diff changeset
190 def __delitem__(self, key):
068952b4d4c0 Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents: 49
diff changeset
191 dict.__delitem__(self, key)
068952b4d4c0 Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents: 49
diff changeset
192 self._keys.remove(key)
068952b4d4c0 Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents: 49
diff changeset
193
068952b4d4c0 Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents: 49
diff changeset
194 def __setitem__(self, key, item):
068952b4d4c0 Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents: 49
diff changeset
195 dict.__setitem__(self, key, item)
068952b4d4c0 Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents: 49
diff changeset
196 if key not in self._keys:
068952b4d4c0 Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents: 49
diff changeset
197 self._keys.append(key)
068952b4d4c0 Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents: 49
diff changeset
198
068952b4d4c0 Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents: 49
diff changeset
199 def __iter__(self):
068952b4d4c0 Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents: 49
diff changeset
200 return iter(self._keys)
339
6811369cb912 Fix iterkeys/iteritems/itervalues/pop/popitem methods on the `odict` utility class. Thanks to Armin Ronacher for the patch.
cmlenz
parents: 330
diff changeset
201 iterkeys = __iter__
58
068952b4d4c0 Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents: 49
diff changeset
202
068952b4d4c0 Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents: 49
diff changeset
203 def clear(self):
068952b4d4c0 Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents: 49
diff changeset
204 dict.clear(self)
068952b4d4c0 Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents: 49
diff changeset
205 self._keys = []
068952b4d4c0 Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents: 49
diff changeset
206
068952b4d4c0 Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents: 49
diff changeset
207 def copy(self):
068952b4d4c0 Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents: 49
diff changeset
208 d = odict()
068952b4d4c0 Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents: 49
diff changeset
209 d.update(self)
068952b4d4c0 Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents: 49
diff changeset
210 return d
068952b4d4c0 Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents: 49
diff changeset
211
068952b4d4c0 Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents: 49
diff changeset
212 def items(self):
068952b4d4c0 Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents: 49
diff changeset
213 return zip(self._keys, self.values())
068952b4d4c0 Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents: 49
diff changeset
214
339
6811369cb912 Fix iterkeys/iteritems/itervalues/pop/popitem methods on the `odict` utility class. Thanks to Armin Ronacher for the patch.
cmlenz
parents: 330
diff changeset
215 def iteritems(self):
6811369cb912 Fix iterkeys/iteritems/itervalues/pop/popitem methods on the `odict` utility class. Thanks to Armin Ronacher for the patch.
cmlenz
parents: 330
diff changeset
216 return izip(self._keys, self.itervalues())
6811369cb912 Fix iterkeys/iteritems/itervalues/pop/popitem methods on the `odict` utility class. Thanks to Armin Ronacher for the patch.
cmlenz
parents: 330
diff changeset
217
58
068952b4d4c0 Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents: 49
diff changeset
218 def keys(self):
068952b4d4c0 Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents: 49
diff changeset
219 return self._keys[:]
068952b4d4c0 Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents: 49
diff changeset
220
339
6811369cb912 Fix iterkeys/iteritems/itervalues/pop/popitem methods on the `odict` utility class. Thanks to Armin Ronacher for the patch.
cmlenz
parents: 330
diff changeset
221 def pop(self, key, default=missing):
6811369cb912 Fix iterkeys/iteritems/itervalues/pop/popitem methods on the `odict` utility class. Thanks to Armin Ronacher for the patch.
cmlenz
parents: 330
diff changeset
222 if default is missing:
6811369cb912 Fix iterkeys/iteritems/itervalues/pop/popitem methods on the `odict` utility class. Thanks to Armin Ronacher for the patch.
cmlenz
parents: 330
diff changeset
223 return dict.pop(self, key)
6811369cb912 Fix iterkeys/iteritems/itervalues/pop/popitem methods on the `odict` utility class. Thanks to Armin Ronacher for the patch.
cmlenz
parents: 330
diff changeset
224 elif key not in self:
167
533baef258bb Implement fuzzy matching to catalog updates. No frontend yet.
cmlenz
parents: 166
diff changeset
225 return default
533baef258bb Implement fuzzy matching to catalog updates. No frontend yet.
cmlenz
parents: 166
diff changeset
226 self._keys.remove(key)
339
6811369cb912 Fix iterkeys/iteritems/itervalues/pop/popitem methods on the `odict` utility class. Thanks to Armin Ronacher for the patch.
cmlenz
parents: 330
diff changeset
227 return dict.pop(self, key, default)
6811369cb912 Fix iterkeys/iteritems/itervalues/pop/popitem methods on the `odict` utility class. Thanks to Armin Ronacher for the patch.
cmlenz
parents: 330
diff changeset
228
6811369cb912 Fix iterkeys/iteritems/itervalues/pop/popitem methods on the `odict` utility class. Thanks to Armin Ronacher for the patch.
cmlenz
parents: 330
diff changeset
229 def popitem(self, key):
6811369cb912 Fix iterkeys/iteritems/itervalues/pop/popitem methods on the `odict` utility class. Thanks to Armin Ronacher for the patch.
cmlenz
parents: 330
diff changeset
230 self._keys.remove(key)
6811369cb912 Fix iterkeys/iteritems/itervalues/pop/popitem methods on the `odict` utility class. Thanks to Armin Ronacher for the patch.
cmlenz
parents: 330
diff changeset
231 return dict.popitem(key)
167
533baef258bb Implement fuzzy matching to catalog updates. No frontend yet.
cmlenz
parents: 166
diff changeset
232
58
068952b4d4c0 Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents: 49
diff changeset
233 def setdefault(self, key, failobj = None):
068952b4d4c0 Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents: 49
diff changeset
234 dict.setdefault(self, key, failobj)
068952b4d4c0 Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents: 49
diff changeset
235 if key not in self._keys:
068952b4d4c0 Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents: 49
diff changeset
236 self._keys.append(key)
068952b4d4c0 Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents: 49
diff changeset
237
068952b4d4c0 Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents: 49
diff changeset
238 def update(self, dict):
068952b4d4c0 Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents: 49
diff changeset
239 for (key, val) in dict.items():
068952b4d4c0 Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents: 49
diff changeset
240 self[key] = val
068952b4d4c0 Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents: 49
diff changeset
241
068952b4d4c0 Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents: 49
diff changeset
242 def values(self):
068952b4d4c0 Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents: 49
diff changeset
243 return map(self.get, self._keys)
068952b4d4c0 Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents: 49
diff changeset
244
339
6811369cb912 Fix iterkeys/iteritems/itervalues/pop/popitem methods on the `odict` utility class. Thanks to Armin Ronacher for the patch.
cmlenz
parents: 330
diff changeset
245 def itervalues(self):
6811369cb912 Fix iterkeys/iteritems/itervalues/pop/popitem methods on the `odict` utility class. Thanks to Armin Ronacher for the patch.
cmlenz
parents: 330
diff changeset
246 return imap(self.get, self._keys)
6811369cb912 Fix iterkeys/iteritems/itervalues/pop/popitem methods on the `odict` utility class. Thanks to Armin Ronacher for the patch.
cmlenz
parents: 330
diff changeset
247
58
068952b4d4c0 Add actual data structures for handling message catalogs, so that more code can be reused here between the frontends.
cmlenz
parents: 49
diff changeset
248
3
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
249 try:
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
250 relpath = os.path.relpath
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
251 except AttributeError:
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
252 def relpath(path, start='.'):
31
3956bb7ff93b More work on timezones.
cmlenz
parents: 15
diff changeset
253 """Compute the relative path to one path from another.
3956bb7ff93b More work on timezones.
cmlenz
parents: 15
diff changeset
254
132
aba61e4bdecf Make `relpath` doctest Windows-compatible.
cmlenz
parents: 108
diff changeset
255 >>> relpath('foo/bar.txt', '').replace(os.sep, '/')
46
0f140f1092e3 Some work towards #4.
cmlenz
parents: 41
diff changeset
256 'foo/bar.txt'
132
aba61e4bdecf Make `relpath` doctest Windows-compatible.
cmlenz
parents: 108
diff changeset
257 >>> relpath('foo/bar.txt', 'foo').replace(os.sep, '/')
46
0f140f1092e3 Some work towards #4.
cmlenz
parents: 41
diff changeset
258 'bar.txt'
132
aba61e4bdecf Make `relpath` doctest Windows-compatible.
cmlenz
parents: 108
diff changeset
259 >>> relpath('foo/bar.txt', 'baz').replace(os.sep, '/')
46
0f140f1092e3 Some work towards #4.
cmlenz
parents: 41
diff changeset
260 '../foo/bar.txt'
0f140f1092e3 Some work towards #4.
cmlenz
parents: 41
diff changeset
261
31
3956bb7ff93b More work on timezones.
cmlenz
parents: 15
diff changeset
262 :return: the relative path
3956bb7ff93b More work on timezones.
cmlenz
parents: 15
diff changeset
263 :rtype: `basestring`
3956bb7ff93b More work on timezones.
cmlenz
parents: 15
diff changeset
264 """
3
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
265 start_list = os.path.abspath(start).split(os.sep)
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
266 path_list = os.path.abspath(path).split(os.sep)
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
267
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
268 # Work out how much of the filepath is shared by start and path.
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
269 i = len(os.path.commonprefix([start_list, path_list]))
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
270
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
271 rel_list = [os.path.pardir] * (len(start_list) - i) + path_list[i:]
e9eaddab598e Import of initial code base.
cmlenz
parents:
diff changeset
272 return os.path.join(*rel_list)
31
3956bb7ff93b More work on timezones.
cmlenz
parents: 15
diff changeset
273
108
8ea225f33f28 Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents: 99
diff changeset
274 ZERO = timedelta(0)
8ea225f33f28 Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents: 99
diff changeset
275
8ea225f33f28 Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents: 99
diff changeset
276
8ea225f33f28 Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents: 99
diff changeset
277 class FixedOffsetTimezone(tzinfo):
8ea225f33f28 Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents: 99
diff changeset
278 """Fixed offset in minutes east from UTC."""
8ea225f33f28 Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents: 99
diff changeset
279
8ea225f33f28 Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents: 99
diff changeset
280 def __init__(self, offset, name=None):
8ea225f33f28 Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents: 99
diff changeset
281 self._offset = timedelta(minutes=offset)
8ea225f33f28 Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents: 99
diff changeset
282 if name is None:
8ea225f33f28 Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents: 99
diff changeset
283 name = 'Etc/GMT+%d' % offset
8ea225f33f28 Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents: 99
diff changeset
284 self.zone = name
8ea225f33f28 Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents: 99
diff changeset
285
8ea225f33f28 Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents: 99
diff changeset
286 def __str__(self):
8ea225f33f28 Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents: 99
diff changeset
287 return self.zone
8ea225f33f28 Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents: 99
diff changeset
288
8ea225f33f28 Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents: 99
diff changeset
289 def __repr__(self):
8ea225f33f28 Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents: 99
diff changeset
290 return '<FixedOffset "%s" %s>' % (self.zone, self._offset)
8ea225f33f28 Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents: 99
diff changeset
291
8ea225f33f28 Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents: 99
diff changeset
292 def utcoffset(self, dt):
8ea225f33f28 Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents: 99
diff changeset
293 return self._offset
8ea225f33f28 Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents: 99
diff changeset
294
8ea225f33f28 Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents: 99
diff changeset
295 def tzname(self, dt):
8ea225f33f28 Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents: 99
diff changeset
296 return self.zone
8ea225f33f28 Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents: 99
diff changeset
297
8ea225f33f28 Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents: 99
diff changeset
298 def dst(self, dt):
8ea225f33f28 Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents: 99
diff changeset
299 return ZERO
8ea225f33f28 Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents: 99
diff changeset
300
8ea225f33f28 Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents: 99
diff changeset
301
31
3956bb7ff93b More work on timezones.
cmlenz
parents: 15
diff changeset
302 try:
3956bb7ff93b More work on timezones.
cmlenz
parents: 15
diff changeset
303 from pytz import UTC
3956bb7ff93b More work on timezones.
cmlenz
parents: 15
diff changeset
304 except ImportError:
108
8ea225f33f28 Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents: 99
diff changeset
305 UTC = FixedOffsetTimezone(0, 'UTC')
31
3956bb7ff93b More work on timezones.
cmlenz
parents: 15
diff changeset
306 """`tzinfo` object for UTC (Universal Time).
3956bb7ff93b More work on timezones.
cmlenz
parents: 15
diff changeset
307
3956bb7ff93b More work on timezones.
cmlenz
parents: 15
diff changeset
308 :type: `tzinfo`
3956bb7ff93b More work on timezones.
cmlenz
parents: 15
diff changeset
309 """
97
debd9ac3bb4d Fix for #11 (use local timezone in timestamps of generated POT).
cmlenz
parents: 64
diff changeset
310
debd9ac3bb4d Fix for #11 (use local timezone in timestamps of generated POT).
cmlenz
parents: 64
diff changeset
311 STDOFFSET = timedelta(seconds = -time.timezone)
debd9ac3bb4d Fix for #11 (use local timezone in timestamps of generated POT).
cmlenz
parents: 64
diff changeset
312 if time.daylight:
debd9ac3bb4d Fix for #11 (use local timezone in timestamps of generated POT).
cmlenz
parents: 64
diff changeset
313 DSTOFFSET = timedelta(seconds = -time.altzone)
debd9ac3bb4d Fix for #11 (use local timezone in timestamps of generated POT).
cmlenz
parents: 64
diff changeset
314 else:
debd9ac3bb4d Fix for #11 (use local timezone in timestamps of generated POT).
cmlenz
parents: 64
diff changeset
315 DSTOFFSET = STDOFFSET
debd9ac3bb4d Fix for #11 (use local timezone in timestamps of generated POT).
cmlenz
parents: 64
diff changeset
316
debd9ac3bb4d Fix for #11 (use local timezone in timestamps of generated POT).
cmlenz
parents: 64
diff changeset
317 DSTDIFF = DSTOFFSET - STDOFFSET
debd9ac3bb4d Fix for #11 (use local timezone in timestamps of generated POT).
cmlenz
parents: 64
diff changeset
318
108
8ea225f33f28 Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents: 99
diff changeset
319
97
debd9ac3bb4d Fix for #11 (use local timezone in timestamps of generated POT).
cmlenz
parents: 64
diff changeset
320 class LocalTimezone(tzinfo):
debd9ac3bb4d Fix for #11 (use local timezone in timestamps of generated POT).
cmlenz
parents: 64
diff changeset
321
debd9ac3bb4d Fix for #11 (use local timezone in timestamps of generated POT).
cmlenz
parents: 64
diff changeset
322 def utcoffset(self, dt):
debd9ac3bb4d Fix for #11 (use local timezone in timestamps of generated POT).
cmlenz
parents: 64
diff changeset
323 if self._isdst(dt):
debd9ac3bb4d Fix for #11 (use local timezone in timestamps of generated POT).
cmlenz
parents: 64
diff changeset
324 return DSTOFFSET
debd9ac3bb4d Fix for #11 (use local timezone in timestamps of generated POT).
cmlenz
parents: 64
diff changeset
325 else:
debd9ac3bb4d Fix for #11 (use local timezone in timestamps of generated POT).
cmlenz
parents: 64
diff changeset
326 return STDOFFSET
debd9ac3bb4d Fix for #11 (use local timezone in timestamps of generated POT).
cmlenz
parents: 64
diff changeset
327
debd9ac3bb4d Fix for #11 (use local timezone in timestamps of generated POT).
cmlenz
parents: 64
diff changeset
328 def dst(self, dt):
debd9ac3bb4d Fix for #11 (use local timezone in timestamps of generated POT).
cmlenz
parents: 64
diff changeset
329 if self._isdst(dt):
debd9ac3bb4d Fix for #11 (use local timezone in timestamps of generated POT).
cmlenz
parents: 64
diff changeset
330 return DSTDIFF
debd9ac3bb4d Fix for #11 (use local timezone in timestamps of generated POT).
cmlenz
parents: 64
diff changeset
331 else:
debd9ac3bb4d Fix for #11 (use local timezone in timestamps of generated POT).
cmlenz
parents: 64
diff changeset
332 return ZERO
debd9ac3bb4d Fix for #11 (use local timezone in timestamps of generated POT).
cmlenz
parents: 64
diff changeset
333
debd9ac3bb4d Fix for #11 (use local timezone in timestamps of generated POT).
cmlenz
parents: 64
diff changeset
334 def tzname(self, dt):
debd9ac3bb4d Fix for #11 (use local timezone in timestamps of generated POT).
cmlenz
parents: 64
diff changeset
335 return time.tzname[self._isdst(dt)]
debd9ac3bb4d Fix for #11 (use local timezone in timestamps of generated POT).
cmlenz
parents: 64
diff changeset
336
debd9ac3bb4d Fix for #11 (use local timezone in timestamps of generated POT).
cmlenz
parents: 64
diff changeset
337 def _isdst(self, dt):
debd9ac3bb4d Fix for #11 (use local timezone in timestamps of generated POT).
cmlenz
parents: 64
diff changeset
338 tt = (dt.year, dt.month, dt.day,
debd9ac3bb4d Fix for #11 (use local timezone in timestamps of generated POT).
cmlenz
parents: 64
diff changeset
339 dt.hour, dt.minute, dt.second,
debd9ac3bb4d Fix for #11 (use local timezone in timestamps of generated POT).
cmlenz
parents: 64
diff changeset
340 dt.weekday(), 0, -1)
debd9ac3bb4d Fix for #11 (use local timezone in timestamps of generated POT).
cmlenz
parents: 64
diff changeset
341 stamp = time.mktime(tt)
debd9ac3bb4d Fix for #11 (use local timezone in timestamps of generated POT).
cmlenz
parents: 64
diff changeset
342 tt = time.localtime(stamp)
debd9ac3bb4d Fix for #11 (use local timezone in timestamps of generated POT).
cmlenz
parents: 64
diff changeset
343 return tt.tm_isdst > 0
debd9ac3bb4d Fix for #11 (use local timezone in timestamps of generated POT).
cmlenz
parents: 64
diff changeset
344
108
8ea225f33f28 Fix for #16: the header message (`msgid = ""`) is now treated specially by `read_po` and `Catalog`.
cmlenz
parents: 99
diff changeset
345
99
b6b5992daa6c Renamed `LOCAL` to `LOCALTZ`.
cmlenz
parents: 97
diff changeset
346 LOCALTZ = LocalTimezone()
b6b5992daa6c Renamed `LOCAL` to `LOCALTZ`.
cmlenz
parents: 97
diff changeset
347 """`tzinfo` object for local time-zone.
b6b5992daa6c Renamed `LOCAL` to `LOCALTZ`.
cmlenz
parents: 97
diff changeset
348
b6b5992daa6c Renamed `LOCAL` to `LOCALTZ`.
cmlenz
parents: 97
diff changeset
349 :type: `tzinfo`
b6b5992daa6c Renamed `LOCAL` to `LOCALTZ`.
cmlenz
parents: 97
diff changeset
350 """
Copyright (C) 2012-2017 Edgewall Software