summaryrefslogtreecommitdiffstats
path: root/Lib/gettext.py
diff options
context:
space:
mode:
authorMartin v. Löwis <martin@v.loewis.de>2002-01-11 06:58:49 (GMT)
committerMartin v. Löwis <martin@v.loewis.de>2002-01-11 06:58:49 (GMT)
commita55ffaeee9eb2fba62f280c364b3460fafd9efc9 (patch)
tree331b0e42419b62122394edda64ccee92118a316b /Lib/gettext.py
parent1be641987145f88d61e52d5b4714a8cc6c7e6da8 (diff)
downloadcpython-a55ffaeee9eb2fba62f280c364b3460fafd9efc9.zip
cpython-a55ffaeee9eb2fba62f280c364b3460fafd9efc9.tar.gz
cpython-a55ffaeee9eb2fba62f280c364b3460fafd9efc9.tar.bz2
Add a per-message fallback mechanism for translations.
Diffstat (limited to 'Lib/gettext.py')
-rw-r--r--Lib/gettext.py63
1 files changed, 50 insertions, 13 deletions
diff --git a/Lib/gettext.py b/Lib/gettext.py
index 6795ee6..0bea9ed 100644
--- a/Lib/gettext.py
+++ b/Lib/gettext.py
@@ -46,6 +46,7 @@ internationalized, to the local language and cultural habits.
import os
import sys
import struct
+import copy
from errno import ENOENT
__all__ = ["bindtextdomain","textdomain","gettext","dgettext",
@@ -102,16 +103,27 @@ class NullTranslations:
def __init__(self, fp=None):
self._info = {}
self._charset = None
+ self._fallback = None
if fp:
self._parse(fp)
def _parse(self, fp):
pass
+ def add_fallback(self, fallback):
+ if self._fallback:
+ self._fallback.add_fallback(fallback)
+ else:
+ self._fallback = fallback
+
def gettext(self, message):
+ if self._fallback:
+ return self._fallback.gettext(message)
return message
def ugettext(self, message):
+ if self._fallback:
+ return self._fallback.ugettext(message)
return unicode(message)
def info(self):
@@ -188,16 +200,26 @@ class GNUTranslations(NullTranslations):
transidx += 8
def gettext(self, message):
- return self._catalog.get(message, message)
+ try:
+ return self._catalog[message]
+ except KeyError:
+ if self._fallback:
+ return self._fallback.gettext(message)
+ return message
def ugettext(self, message):
- tmsg = self._catalog.get(message, message)
+ try:
+ tmsg = self._catalog[message]
+ except KeyError:
+ if self._fallback:
+ return self._fallback.ugettext(message)
+ tmsg = message
return unicode(tmsg, self._charset)
# Locate a .mo file using the gettext strategy
-def find(domain, localedir=None, languages=None):
+def find(domain, localedir=None, languages=None, all=0):
# Get some reasonable defaults for arguments that were not supplied
if localedir is None:
localedir = _default_localedir
@@ -217,13 +239,20 @@ def find(domain, localedir=None, languages=None):
if nelang not in nelangs:
nelangs.append(nelang)
# select a language
+ if all:
+ result = []
+ else:
+ result = None
for lang in nelangs:
if lang == 'C':
break
mofile = os.path.join(localedir, lang, 'LC_MESSAGES', '%s.mo' % domain)
if os.path.exists(mofile):
- return mofile
- return None
+ if all:
+ result.append(mofile)
+ else:
+ return mofile
+ return result
@@ -234,20 +263,28 @@ def translation(domain, localedir=None, languages=None,
class_=None, fallback=0):
if class_ is None:
class_ = GNUTranslations
- mofile = find(domain, localedir, languages)
- if mofile is None:
+ mofiles = find(domain, localedir, languages, all=1)
+ if len(mofiles)==0:
if fallback:
return NullTranslations()
raise IOError(ENOENT, 'No translation file found for domain', domain)
- key = os.path.abspath(mofile)
# TBD: do we need to worry about the file pointer getting collected?
# Avoid opening, reading, and parsing the .mo file after it's been done
# once.
- t = _translations.get(key)
- if t is None:
- t = _translations.setdefault(key, class_(open(mofile, 'rb')))
- return t
-
+ result = None
+ for mofile in mofiles:
+ key = os.path.abspath(mofile)
+ t = _translations.get(key)
+ if t is None:
+ t = _translations.setdefault(key, class_(open(mofile, 'rb')))
+ # Copy the translation object to allow setting fallbacks.
+ # All other instance data is shared with the cached object.
+ t = copy.copy(t)
+ if result is None:
+ result = t
+ else:
+ result.add_fallback(t)
+ return result
def install(domain, localedir=None, unicode=0):