Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
a55ffaee
Commit
a55ffaee
authored
Jan 11, 2002
by
Martin v. Löwis
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add a per-message fallback mechanism for translations.
parent
1be64198
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
84 additions
and
26 deletions
+84
-26
Doc/lib/libgettext.tex
Doc/lib/libgettext.tex
+31
-12
Lib/gettext.py
Lib/gettext.py
+50
-13
Misc/NEWS
Misc/NEWS
+3
-1
No files found.
Doc/lib/libgettext.tex
View file @
a55ffaee
...
...
@@ -95,7 +95,8 @@ for returning either standard 8-bit strings or Unicode strings.
Translations instances can also install themselves in the built-in
namespace as the function
\function
{_
()
}
.
\begin{funcdesc}
{
find
}{
domain
\optional
{
, localedir
\optional
{
, languages
}}}
\begin{funcdesc}
{
find
}{
domain
\optional
{
, localedir
\optional
{
,
languages
\optional
{
, all
}}}}
This function implements the standard
\file
{
.mo
}
file search
algorithm. It takes a
\var
{
domain
}
, identical to what
\function
{
textdomain()
}
takes. Optional
\var
{
localedir
}
is as in
...
...
@@ -119,7 +120,9 @@ components:
\file
{
\var
{
localedir
}
/
\var
{
language
}
/LC
_
MESSAGES/
\var
{
domain
}
.mo
}
The first such file name that exists is returned by
\function
{
find()
}
.
If no such file is found, then
\code
{
None
}
is returned.
If no such file is found, then
\code
{
None
}
is returned. If
\var
{
all
}
is given, it returns a list of all file names, in the order in which
they appear in the languages list or the environment variables.
\end{funcdesc}
\begin{funcdesc}
{
translation
}{
domain
\optional
{
, localedir
\optional
{
,
...
...
@@ -127,15 +130,22 @@ If no such file is found, then \code{None} is returned.
class
_
,
\optional
{
fallback
}}}}}
Return a
\class
{
Translations
}
instance based on the
\var
{
domain
}
,
\var
{
localedir
}
, and
\var
{
languages
}
, which are first passed to
\function
{
find()
}
to get the
associated
\file
{
.mo
}
file path. Instances with
\function
{
find()
}
to get
a list of
the
associated
\file
{
.mo
}
file path
s
. Instances with
identical
\file
{
.mo
}
file names are cached. The actual class instantiated
is either
\var
{
class
_}
if provided, otherwise
\class
{
GNUTranslations
}
. The class's constructor must take a single
file object argument. If no
\file
{
.mo
}
file is found, this
function raises
\exception
{
IOError
}
if
\var
{
fallback
}
is false
(which is the default), and returns a
\class
{
NullTranslations
}
instance
if
\var
{
fallback
}
is true.
file object argument.
If multiple files are found, later files are used as fallbacks for
earlier ones. To allow setting the fallback,
\function
{
copy.copy
}
is used to clone each translation object from the cache; the actual
instance data is still shared with the cache.
If no
\file
{
.mo
}
file is found, this function raises
\exception
{
IOError
}
if
\var
{
fallback
}
is false (which is the default),
and returns a
\class
{
NullTranslations
}
instance if
\var
{
fallback
}
is
true.
\end{funcdesc}
\begin{funcdesc}
{
install
}{
domain
\optional
{
, localedir
\optional
{
, unicode
}}}
...
...
@@ -168,7 +178,8 @@ methods of \class{NullTranslations}:
\begin{methoddesc}
[NullTranslations]
{__
init
__}{
\optional
{
fp
}}
Takes an optional file object
\var
{
fp
}
, which is ignored by the base
class. Initializes ``protected'' instance variables
\var
{_
info
}
and
\var
{_
charset
}
which are set by derived classes. It then calls
\var
{_
charset
}
which are set by derived classes, as well as
\var
{_
fallback
}
,
which is set through
\method
{
add
_
fallback
}
. It then calls
\code
{
self.
_
parse(fp)
}
if
\var
{
fp
}
is not
\code
{
None
}
.
\end{methoddesc}
...
...
@@ -179,13 +190,21 @@ you have an unsupported message catalog file format, you should
override this method to parse your format.
\end{methoddesc}
\begin{methoddesc}
{
NullTranslations
}{
add
_
fallback
}{
fallback
}
Add
\var
{
fallback
}
as the fallback object for the current translation
object. A translation object should consult the fallback if it cannot
provide a translation for a given message.
\end{methoddesc}
\begin{methoddesc}
[NullTranslations]
{
gettext
}{
message
}
Return the translated message. Overridden in derived classes.
If a fallback has been set, forward
\method
{
gettext
}
to the fallback.
Otherwise, return the translated message. Overridden in derived classes.
\end{methoddesc}
\begin{methoddesc}
[NullTranslations]
{
ugettext
}{
message
}
Return the translated message as a Unicode string. Overridden in
derived classes.
If a fallback has been set, forward
\method
{
ugettext
}
to the fallback.
Otherwise, return the translated message as a Unicode string.
Overridden in derived classes.
\end{methoddesc}
\begin{methoddesc}
[NullTranslations]
{
info
}{}
...
...
Lib/gettext.py
View file @
a55ffaee
...
...
@@ -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
:
mofile
s
=
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
):
...
...
Misc/NEWS
View file @
a55ffaee
...
...
@@ -26,7 +26,9 @@ Library
arbitrary shell code can't be executed because a bogus URL was
passed in.
- gettext.translation has an optional fallback argument.
- gettext.translation has an optional fallback argument, and
gettext.find an optional all argument. Translations will now fallback
on a per-message basis.
Tools/Demos
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment