Mercurial > hg
annotate mercurial/i18n.py @ 21812:73e4a02e6d23
hg: add support for HGUNICODEPEDANTRY environment variable
This lets us easily verify that there are no implicit conversions
between unicodes and bytes in Mercurial's codebase. Based on something
mpm did by hand periodically, but it kept regressing, so just open the
door to running it in a buildbot.
author | Augie Fackler <raf@durin42.com> |
---|---|
date | Mon, 23 Jun 2014 09:33:07 -0400 |
parents | 2d47d81c79fb |
children | 4953cd193e84 |
rev | line source |
---|---|
8226
8b2cd04a6e97
put license and copyright info into comment blocks
Martin Geisler <mg@lazybytes.net>
parents:
8225
diff
changeset
|
1 # i18n.py - internationalization support for mercurial |
8b2cd04a6e97
put license and copyright info into comment blocks
Martin Geisler <mg@lazybytes.net>
parents:
8225
diff
changeset
|
2 # |
8b2cd04a6e97
put license and copyright info into comment blocks
Martin Geisler <mg@lazybytes.net>
parents:
8225
diff
changeset
|
3 # Copyright 2005, 2006 Matt Mackall <mpm@selenic.com> |
8b2cd04a6e97
put license and copyright info into comment blocks
Martin Geisler <mg@lazybytes.net>
parents:
8225
diff
changeset
|
4 # |
8b2cd04a6e97
put license and copyright info into comment blocks
Martin Geisler <mg@lazybytes.net>
parents:
8225
diff
changeset
|
5 # This software may be used and distributed according to the terms of the |
10263 | 6 # GNU General Public License version 2 or any later version. |
1400
cf9a1233738a
i18n first part: make '_' available for files who need it
Benoit Boissinot <benoit.boissinot@ens-lyon.org
parents:
diff
changeset
|
7 |
8312
b87a50b7125c
separate import lines from mercurial and general python modules
Simon Heimberg <simohe@besonet.ch>
parents:
8226
diff
changeset
|
8 import encoding |
b87a50b7125c
separate import lines from mercurial and general python modules
Simon Heimberg <simohe@besonet.ch>
parents:
8226
diff
changeset
|
9 import gettext, sys, os |
7650
85ae7aaf08e9
i18n: lookup .mo files in private locale/ directory
Martin Geisler <mg@daimi.au.dk>
parents:
3888
diff
changeset
|
10 |
85ae7aaf08e9
i18n: lookup .mo files in private locale/ directory
Martin Geisler <mg@daimi.au.dk>
parents:
3888
diff
changeset
|
11 # modelled after templater.templatepath: |
14975
b64538363dbe
i18n: use getattr instead of hasattr
Augie Fackler <durin42@gmail.com>
parents:
13849
diff
changeset
|
12 if getattr(sys, 'frozen', None) is not None: |
7650
85ae7aaf08e9
i18n: lookup .mo files in private locale/ directory
Martin Geisler <mg@daimi.au.dk>
parents:
3888
diff
changeset
|
13 module = sys.executable |
85ae7aaf08e9
i18n: lookup .mo files in private locale/ directory
Martin Geisler <mg@daimi.au.dk>
parents:
3888
diff
changeset
|
14 else: |
85ae7aaf08e9
i18n: lookup .mo files in private locale/ directory
Martin Geisler <mg@daimi.au.dk>
parents:
3888
diff
changeset
|
15 module = __file__ |
85ae7aaf08e9
i18n: lookup .mo files in private locale/ directory
Martin Geisler <mg@daimi.au.dk>
parents:
3888
diff
changeset
|
16 |
85ae7aaf08e9
i18n: lookup .mo files in private locale/ directory
Martin Geisler <mg@daimi.au.dk>
parents:
3888
diff
changeset
|
17 base = os.path.dirname(module) |
85ae7aaf08e9
i18n: lookup .mo files in private locale/ directory
Martin Geisler <mg@daimi.au.dk>
parents:
3888
diff
changeset
|
18 for dir in ('.', '..'): |
9538
f96ee862aba0
i18n: remove unnecessary os.path.normpath call
Martin Geisler <mg@lazybytes.net>
parents:
9320
diff
changeset
|
19 localedir = os.path.join(base, dir, 'locale') |
7650
85ae7aaf08e9
i18n: lookup .mo files in private locale/ directory
Martin Geisler <mg@daimi.au.dk>
parents:
3888
diff
changeset
|
20 if os.path.isdir(localedir): |
85ae7aaf08e9
i18n: lookup .mo files in private locale/ directory
Martin Geisler <mg@daimi.au.dk>
parents:
3888
diff
changeset
|
21 break |
85ae7aaf08e9
i18n: lookup .mo files in private locale/ directory
Martin Geisler <mg@daimi.au.dk>
parents:
3888
diff
changeset
|
22 |
85ae7aaf08e9
i18n: lookup .mo files in private locale/ directory
Martin Geisler <mg@daimi.au.dk>
parents:
3888
diff
changeset
|
23 t = gettext.translation('hg', localedir, fallback=True) |
7651
5b5036ef847a
i18n: encode output in user's local encoding
Martin Geisler <mg@daimi.au.dk>
parents:
7650
diff
changeset
|
24 |
5b5036ef847a
i18n: encode output in user's local encoding
Martin Geisler <mg@daimi.au.dk>
parents:
7650
diff
changeset
|
25 def gettext(message): |
5b5036ef847a
i18n: encode output in user's local encoding
Martin Geisler <mg@daimi.au.dk>
parents:
7650
diff
changeset
|
26 """Translate message. |
5b5036ef847a
i18n: encode output in user's local encoding
Martin Geisler <mg@daimi.au.dk>
parents:
7650
diff
changeset
|
27 |
5b5036ef847a
i18n: encode output in user's local encoding
Martin Geisler <mg@daimi.au.dk>
parents:
7650
diff
changeset
|
28 The message is looked up in the catalog to get a Unicode string, |
5b5036ef847a
i18n: encode output in user's local encoding
Martin Geisler <mg@daimi.au.dk>
parents:
7650
diff
changeset
|
29 which is encoded in the local encoding before being returned. |
5b5036ef847a
i18n: encode output in user's local encoding
Martin Geisler <mg@daimi.au.dk>
parents:
7650
diff
changeset
|
30 |
5b5036ef847a
i18n: encode output in user's local encoding
Martin Geisler <mg@daimi.au.dk>
parents:
7650
diff
changeset
|
31 Important: message is restricted to characters in the encoding |
5b5036ef847a
i18n: encode output in user's local encoding
Martin Geisler <mg@daimi.au.dk>
parents:
7650
diff
changeset
|
32 given by sys.getdefaultencoding() which is most likely 'ascii'. |
5b5036ef847a
i18n: encode output in user's local encoding
Martin Geisler <mg@daimi.au.dk>
parents:
7650
diff
changeset
|
33 """ |
5b5036ef847a
i18n: encode output in user's local encoding
Martin Geisler <mg@daimi.au.dk>
parents:
7650
diff
changeset
|
34 # If message is None, t.ugettext will return u'None' as the |
5b5036ef847a
i18n: encode output in user's local encoding
Martin Geisler <mg@daimi.au.dk>
parents:
7650
diff
changeset
|
35 # translation whereas our callers expect us to return None. |
5b5036ef847a
i18n: encode output in user's local encoding
Martin Geisler <mg@daimi.au.dk>
parents:
7650
diff
changeset
|
36 if message is None: |
5b5036ef847a
i18n: encode output in user's local encoding
Martin Geisler <mg@daimi.au.dk>
parents:
7650
diff
changeset
|
37 return message |
5b5036ef847a
i18n: encode output in user's local encoding
Martin Geisler <mg@daimi.au.dk>
parents:
7650
diff
changeset
|
38 |
21746
2d47d81c79fb
i18n: explicitly decode paragraphs
Matt Mackall <mpm@selenic.com>
parents:
14975
diff
changeset
|
39 if type(message) is unicode: |
2d47d81c79fb
i18n: explicitly decode paragraphs
Matt Mackall <mpm@selenic.com>
parents:
14975
diff
changeset
|
40 # goofy unicode docstrings in test |
2d47d81c79fb
i18n: explicitly decode paragraphs
Matt Mackall <mpm@selenic.com>
parents:
14975
diff
changeset
|
41 paragraphs = message.split(u'\n\n') |
2d47d81c79fb
i18n: explicitly decode paragraphs
Matt Mackall <mpm@selenic.com>
parents:
14975
diff
changeset
|
42 else: |
2d47d81c79fb
i18n: explicitly decode paragraphs
Matt Mackall <mpm@selenic.com>
parents:
14975
diff
changeset
|
43 paragraphs = [p.decode("ascii") for p in message.split('\n\n')] |
11403
f7d7de6eccc8
i18n: fix translation of empty paragraphs
Martin Geisler <mg@lazybytes.net>
parents:
11390
diff
changeset
|
44 # Be careful not to translate the empty string -- it holds the |
f7d7de6eccc8
i18n: fix translation of empty paragraphs
Martin Geisler <mg@lazybytes.net>
parents:
11390
diff
changeset
|
45 # meta data of the .po file. |
f7d7de6eccc8
i18n: fix translation of empty paragraphs
Martin Geisler <mg@lazybytes.net>
parents:
11390
diff
changeset
|
46 u = u'\n\n'.join([p and t.ugettext(p) or '' for p in paragraphs]) |
7651
5b5036ef847a
i18n: encode output in user's local encoding
Martin Geisler <mg@daimi.au.dk>
parents:
7650
diff
changeset
|
47 try: |
9319
8982eb292cb5
i18n: updated outdated comment
Martin Geisler <mg@lazybytes.net>
parents:
8312
diff
changeset
|
48 # encoding.tolocal cannot be used since it will first try to |
8982eb292cb5
i18n: updated outdated comment
Martin Geisler <mg@lazybytes.net>
parents:
8312
diff
changeset
|
49 # decode the Unicode string. Calling u.decode(enc) really |
8982eb292cb5
i18n: updated outdated comment
Martin Geisler <mg@lazybytes.net>
parents:
8312
diff
changeset
|
50 # means u.encode(sys.getdefaultencoding()).decode(enc). Since |
8982eb292cb5
i18n: updated outdated comment
Martin Geisler <mg@lazybytes.net>
parents:
8312
diff
changeset
|
51 # the Python encoding defaults to 'ascii', this fails if the |
8982eb292cb5
i18n: updated outdated comment
Martin Geisler <mg@lazybytes.net>
parents:
8312
diff
changeset
|
52 # translated string use non-ASCII characters. |
7948
de377b1a9a84
move encoding bits from util to encoding
Matt Mackall <mpm@selenic.com>
parents:
7651
diff
changeset
|
53 return u.encode(encoding.encoding, "replace") |
7651
5b5036ef847a
i18n: encode output in user's local encoding
Martin Geisler <mg@daimi.au.dk>
parents:
7650
diff
changeset
|
54 except LookupError: |
9320
884964f99e07
i18n: move unrelated line out of try-except block
Martin Geisler <mg@lazybytes.net>
parents:
9319
diff
changeset
|
55 # An unknown encoding results in a LookupError. |
7651
5b5036ef847a
i18n: encode output in user's local encoding
Martin Geisler <mg@daimi.au.dk>
parents:
7650
diff
changeset
|
56 return message |
5b5036ef847a
i18n: encode output in user's local encoding
Martin Geisler <mg@daimi.au.dk>
parents:
7650
diff
changeset
|
57 |
13849
9f97de157aad
HGPLAIN: allow exceptions to plain mode, like i18n, via HGPLAINEXCEPT
Brodie Rao <brodie@bitheap.org>
parents:
11403
diff
changeset
|
58 def _plain(): |
9f97de157aad
HGPLAIN: allow exceptions to plain mode, like i18n, via HGPLAINEXCEPT
Brodie Rao <brodie@bitheap.org>
parents:
11403
diff
changeset
|
59 if 'HGPLAIN' not in os.environ and 'HGPLAINEXCEPT' not in os.environ: |
9f97de157aad
HGPLAIN: allow exceptions to plain mode, like i18n, via HGPLAINEXCEPT
Brodie Rao <brodie@bitheap.org>
parents:
11403
diff
changeset
|
60 return False |
9f97de157aad
HGPLAIN: allow exceptions to plain mode, like i18n, via HGPLAINEXCEPT
Brodie Rao <brodie@bitheap.org>
parents:
11403
diff
changeset
|
61 exceptions = os.environ.get('HGPLAINEXCEPT', '').strip().split(',') |
9f97de157aad
HGPLAIN: allow exceptions to plain mode, like i18n, via HGPLAINEXCEPT
Brodie Rao <brodie@bitheap.org>
parents:
11403
diff
changeset
|
62 return 'i18n' not in exceptions |
9f97de157aad
HGPLAIN: allow exceptions to plain mode, like i18n, via HGPLAINEXCEPT
Brodie Rao <brodie@bitheap.org>
parents:
11403
diff
changeset
|
63 |
9f97de157aad
HGPLAIN: allow exceptions to plain mode, like i18n, via HGPLAINEXCEPT
Brodie Rao <brodie@bitheap.org>
parents:
11403
diff
changeset
|
64 if _plain(): |
10455
40dfd46d098f
ui: add HGPLAIN environment variable for easier scripting
Brodie Rao <me+hg@dackz.net>
parents:
10263
diff
changeset
|
65 _ = lambda message: message |
40dfd46d098f
ui: add HGPLAIN environment variable for easier scripting
Brodie Rao <me+hg@dackz.net>
parents:
10263
diff
changeset
|
66 else: |
40dfd46d098f
ui: add HGPLAIN environment variable for easier scripting
Brodie Rao <me+hg@dackz.net>
parents:
10263
diff
changeset
|
67 _ = gettext |