annotate babel/util.py @ 530:85e1beadacb0

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