This package implements several APIs related to internationalization and localization.
- Locale objects for all locales maintained by the ICU project.
- Gettext-based message catalogs for message strings.
- Locale discovery for Web-based requests.
APIs and data related to internationalization and localization.
License: Other
In https://bugs.launchpad.net/zope.i18n/+bug/428882, Ethan Jucovy ([email protected]) reported:
It is useful to be able to override the default
zope.i18n.translationdomain.TranslationDomain
-- for example I have one override that always injects a certain value into the translation mapping, and another that prepends all new catalogs rather than appending them.This is currently difficult without monkeypatching
zope.i18n.zcml.handler
or forking itsregisterTranslations
function.The attached patch adds an optional
factory
argument to bothregisterTranslations
andhandler
so that custom ZCML directives can invokeregisterTranslations
with their choice ofITranslationDomain
.It might also be worth checking that the object returned by the provided
factory
implements (or can be adapted to?)ITranslationDomain
, and preventing startup if it does not.The
<registerTranslations/>
directive could also be extended with an optionalfactory
parameter whose default iszope.i18n.translationdomain.TranslationDomain
. This isn't necessary, though, and it's arguably cleaner to write new directives for particular overrides.
with patch: https://bugs.launchpad.net/zope.i18n/+bug/428882/+attachment/714923/+files/add_factory.diff
.../site-packages/Testing/ZopeTestCase/__init__.py:54: in <module>
from . import placeless # NOQA
.../site-packages/Testing/ZopeTestCase/placeless.py:31: in <module>
ContainerPlacelessSetup):
E TypeError: Error when calling the metaclass bases
E Cannot create a consistent method resolution
E order (MRO) for bases PlacelessSetup, PlacelessSetup, PlacelessSetup, CleanUp
Seems to be the same problem like #30.
In https://bugs.launchpad.net/zope.i18n/+bug/592753, @ctheune reported:
When using the module-level translation function passing in a message ID like shown below the interpolation will not happen because the translate function overrides the passed-in mapping with the (empty) default of the message object.
from foo import MessageFactory as _
X = _('some ${data}')
zope.i18n.translate(X, mapping=dict(data=1))
A work around for users is to explicitly turn the message ID back into a unicode object:
zope.i18n.translate(unicode(X), mapping=dict(data=1))
I usually do:
X = _('some ${data}', mapping=dict(data=1))
zope.i18n.translate(X, context=self.request)
But indeed when you use X as a constant, you don't have necessary the mapping right away. In this case, what I do is to create a new Message object:
from zope.i18nmessageid import Message
zope.i18n.translate(Message(X, mapping=dict(data=1)), context=self.request)
This is the preferred way to do it right now. You lose the domain and default message when you do unicode(X).
Indeed, it may be less verbose to write:
zope.i18n.translate(X, mapping=dict(data=1), context=self.request)
If somebody change the code of the translate function so you can override mapping like this, I think in this case you should be able to override domain and default as well.
@vincentfretin (later):
Christian: Do we replace or update the mapping that's on the message object?
When you create a Message object from a Message object, it replaces the mapping completely, so I'd say we should do the same here, replace the mapping.
Currently it is only possible to override the existing mapping but it might be helpful (in some cases) to update it. I see no need to remove keys from the mapping, so it would be always perfect to update the mapping.
This needs more discussion. My analysis and discussion is here: https://mail.zope.org/pipermail/zope-dev/2010-October/041906.html
Methods defined in interfaces should not list the self
argument. getPluralMessage does. This makes it impossible to use zope.interface's verifyObject() to validate implementations.
zope.i18n.format.NumberFormat
assumes that number thousand grouping is always 3, the grouping by 3 is hardcoded.
zope/i18n/locales/data/en_IN.xml
has the right formatting:
<currencyFormat >
<pattern>¤ ##,##,##0.00;-¤ ##,##,##0.00</pattern>
</currencyFormat>
note that grouping is 2-2-3 for lakh
I have an int field for a "year", how would I disable grouping?
This happened while testing a plone.app.contentrules based workflow transition for a document containing non-ascii characters in the title (Garapaöl). An error status message was generated by url which caused the Traceback below.
I was able to avoid the traceback and get a status message by copying safe_unicode from https://github.com/plone/Products.CMFPlone/blob/master/Products/CMFPlone/utils.py#L453
def replace(match):
whole, param1, param2 = match.groups()
return safe_unicode(mapping.get(param1 or param2, whole))
Error Beim Wechsel des Status von Artikel Garapaöl im Rahmen einer Arbeitsablaufaktion ist ein Fehler aufgetreten: No workflow provides the '${action_id}' action.
Attempting to import safe_unicode results in an aborted server startup:
ZConfig.SchemaResourceError: could not load package ZServer: cannot import name translate
Package name: 'ZServer'
File name: 'component.xml'
Package path: None
2017-02-28 13:33:07 ERROR Zope.SiteErrorLog 1488285187.130.516651919431 http://localhost:8585/mdb/de/produkte/garapaoel/@@edit
Traceback (innermost last):
Module ZPublisher.Publish, line 138, in publish
Module ZPublisher.mapply, line 77, in mapply
Module ZPublisher.Publish, line 48, in call_object
Module plone.z3cform.layout, line 66, in __call__
Module plone.z3cform.layout, line 50, in update
Module plone.dexterity.browser.edit, line 58, in update
Module plone.z3cform.fieldsets.extensible, line 59, in update
Module plone.z3cform.patch, line 30, in GroupForm_update
Module z3c.form.group, line 145, in update
Module plone.app.z3cform.csrf, line 21, in execute
Module z3c.form.action, line 98, in execute
Module z3c.form.button, line 315, in __call__
Module z3c.form.button, line 170, in __call__
Module plone.dexterity.browser.edit, line 30, in handleApply
Module z3c.form.group, line 126, in applyChanges
Module zope.event, line 31, in notify
Module zope.component.event, line 24, in dispatch
Module zope.component._api, line 136, in subscribers
Module zope.component.registry, line 321, in subscribers
Module zope.interface.adapter, line 585, in subscribers
Module plone.app.contentrules.handlers, line 234, in modified
Module plone.app.contentrules.handlers, line 162, in execute_rules
Module plone.app.contentrules.handlers, line 130, in execute
Module plone.contentrules.engine.executor, line 37, in __call__
Module plone.contentrules.rule.rule, line 47, in __call__
Module plone.app.contentrules.actions.workflow, line 65, in __call__
Module plone.app.contentrules.actions.workflow, line 77, in error
Module Products.statusmessages.adapter, line 34, in add
Module zope.i18n, line 127, in translate
Module zope.i18n.translationdomain, line 78, in translate
Module zope.i18n.translationdomain, line 140, in _recursive_translate
Module zope.i18n, line 165, in interpolate
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 15: ordinal not in range(128)
In https://bugs.launchpad.net/zope.i18n/+bug/686058, @wichert reported:
In the nl locale percentages are always formatted without decimals:
>>> locale.numbers.getFormatter("percent").format(50.1)
'50%'
For most other things a locale can format you can use a 'long' length to get more information. No such luck here though:
>>> locale.numbers.getFormatter("percent", length="long").format(50.1)
KeyError: ('long',)
And pin it.
In https://bugs.launchpad.net/zope.i18n/+bug/1073940, Murithi reported:
The versions of LDML files in locales/data are pretty old (released in 2004). Getting any new version from unicode.org: http://unicode.org/repos/cldr/trunk/common/main/ reveals a number of issues:
- Parsing the generation in this format:
<generation date="$Date: 2012-10-11 23:11:48 +0300 (Thu, 11 Oct 2012) $"/>
fails:
File ".../eggs/zope.i18n-3.7.4-py2.7.egg/zope/i18n/locales/xmlfactory.py", line 79, in _extractVersion
generationDate = date(int(year), int(month), int(day))
ValueError: invalid literal for int() with base 10: '$Date: 2012'
- There is an assumption that a date format e.g.:
<dateFormat>
<pattern>MMMM d, y</pattern>
</dateFormat>
implies length for all the date parts - it does not and will fail when formatting dates.
File ".../eggs/zope.i18n-3.7.4-py2.7.egg/zope/i18n/format.py", line 192, in format
text += info.get(elem, elem)
TypeError: coercing to Unicode: need string or buffer, tuple found
<type 'exceptions.TypeError'>:
coercing to Unicode: need string or buffer, tuple found
> /home/undesa/bungeni_apps/bungeni/eggs/zope.i18n-3.7.4-py2.7.egg/zope/i18n/format.py(192)format()
-> text += info.get(elem, elem)
This likely never bombed before since a lookup of the info dictionary always returned a string.
getFormatter (zope/i18n/locales/__init__.py LINE 495)
There are a number of issues with lookup here:
formats = getattr(cal, category+'Formats')
if length is None:
length = getattr(
cal,
'default'+category[0].upper()+category[1:]+'Format',
formats.keys()[0])
# 'datetime' is always a bit special; we often do not have a length
# specification, but we need it for looking up the date and time
# formatters
if category == 'dateTime':
formatLength = formats.get(length, formats[None])
For instance:
length = getattr(cal, 'default'+category[0].upper()+category[1:]+'Format', formats.keys()[0])
Why should this fall back to looking up the format key from the calendar instance?
Also,formats[None]
raises an AttributeError
======================================================================
FAIL: testRegisterAndCompileTranslations (zope.i18n.tests.test_zcml.DirectivesTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/nix-build-python2.7-zope.i18n-4.1.0.drv-0/zope.i18n-4.1.0/src/zope/i18n/tests/test_zcml.py", line 153, in testRegisterAndCompileTranslations
self.assertEqual(msg, _u("I'm a newer file translated"))
AssertionError: u"I'm a newer file" != u"I'm a newer file translated"
- I'm a newer file
+ I'm a newer file translated
? +++++++++++
> pip list
extras (0.0.3)
linecache2 (1.0.0)
lxml (3.7.0)
pbr (1.8.1)
pip (9.0.1)
python-mimeparse (0.1.4)
python-subunit (1.1.0)
pytz (2016.6.1)
setuptools (30.2.0)
six (1.10.0)
testscenarios (0.4)
testtools (1.8.0)
traceback2 (1.4.0)
unittest2 (1.1.0)
wheel (0.29.0)
zope.component (4.2.1)
zope.configuration (4.0.3)
zope.event (4.0.3)
zope.exceptions (4.0.8)
zope.i18nmessageid (4.0.3)
zope.interface (4.1.3)
zope.location (4.0.3)
zope.proxy (4.1.6)
zope.schema (4.4.2)
zope.security (4.0.3)
zope.testing (4.6.1)
zope.testrunner (4.4.10)
In https://bugs.launchpad.net/zope.i18n/+bug/356004, Devin ([email protected]) reported:
When I attempt to use
GettextImportFilter
to parse the gettext translation catalogs inzope.app
forfr
andzh_CN
, I get the following tracebacks (the first isfr
, the second iszh_CN
):
Traceback (most recent call last):
File "./generate-pillar-domain.py", line 68, in main
filter.importMessages(language, fp)
File "/usr/lib/python2.5/site-packages/zope/app/i18n/filters.py", line 95, in importMessages
result = parseGetText(file.readlines())[3]
File "/usr/lib/python2.5/site-packages/zope/app/i18n/filters.py", line 197, in parseGetText
raise ParseError(3, pointer + 1)
ParseError: state 3, line 4382
Traceback (most recent call last):
File "./generate-pillar-domain.py", line 68, in main
filter.importMessages(language, fp)
File "/usr/lib/python2.5/site-packages/zope/app/i18n/filters.py", line 95, in importMessages
result = parseGetText(file.readlines())[3]
File "/usr/lib/python2.5/site-packages/zope/app/i18n/filters.py", line 197, in parseGetText
raise ParseError(3, pointer + 1)
ParseError: state 3, line 268
Both errors occur when a blank line is found at the beginning of a
msgstr
portion in a gettext file.
and later:
Just to clarify, when I say "blank line", I mean "quoted empty string".
It would be more useful to list its canonical VCS repo. That would encourage more contribution.
In https://bugs.launchpad.net/zope.i18n/+bug/374606, @markbarratt reported:
i18n/locales/data/en.xml
has language element names with initial caps:<language type="aa">Afar</language>
.it.xml
has lower-case language names:<language type="af">afrikaans</language>
, as doesde.xml
andes.xml
. Others vary.Not a major bug and fixable in CSS but should be consistent (capitalisation being the convention in most Roman-script-based languages).
In https://bugs.launchpad.net/zope.i18n/+bug/161985, @ccomb reported:
Some languages use the plural form for zero (English, German, Dutch, Italian, Spanish, Portuguese):
This is generated by the ISized adapter of containers :
- "0 items"
- "1 item"
- "2 items"
Regardless of whether this is logical or not to have a plural form for something below 1 :), other languages like French use the plural form only for numbers greater than 1 :
- "0 élément"
- "1 élément"
- "2 élements"
This should be taken into account where applicable (at least on some ISized adapters)
@ctheune follwed up:
zope.i18n does not support plural forms, unfortunately, although it should. The way this is done right now is very hacky.
Could someone do some research on this? What deos it look like and is there a Python implementation for it? I am willing to do the necessary coding, if I get the info I need.
Actually someone made me realize that "zero" is just a typical plural-form, and it can be handled as such. It should be sufficient to use the plural form fonctionnality of gettext where applicable. The string to translate should just be forked into as many plural forms as necessary, and the translators have to translate all these strings separately.
More details here: http://www.gnu.org/software/gettext/manual/html_node/Plural-forms.html
@tmassman:
I added the plural form support in a separate branch: https://code.launchpad.net/~thomas-massmann/zope.i18n/plural. This code was mainly implemented during the 2012 Plonekonf in Munich.
It is already in "production" in a project I'm developing right now. Please note that zope.i18nmessageid needs to be taken from this branch to work: https://code.launchpad.net/~thomas-massmann/zope.i18nmessageid/plural.
Extracting plural messages is supported by xgettext by default. Zope tools like i18nduder have to be adjusted (they don't support ungettext right now). I already adjusted lingua by Wichert Akkerman (https://github.com/tmassman/lingua) - the pull request is still open.
See http://readthedocs.org/projects/zopei18n/builds/
And the hook doesn't seem to be active.
@tseaver could you please take a look? Or you could add me as a maintainer if you'd like.
In https://bugs.launchpad.net/zope.i18n/+bug/668189, @icemac reported:
Creating new message IDs from existing message IDs should behave the following way:
police_and_dog = _('${a} + ${b} = ${c}', mapping=dict(a='police', c='police dog'))
police_dog = _(police_and_dog, mapping=dict(b='dog'))
Currently the mapping for
police_dog
is ignored but I think it should update the mapping ofpolice_and_dog
in the new message ID.Currently you have to do the following to achieve the same:
mapping = police_and_dog.mapping.copy()
mapping.update(dict(b='dog'))
police_dog = _(unicode(police_and_dog), mapping=mapping)
Translating (zope.i18n.translate) should behave the same way.
Something changed in zope.i18n 4.3.0 that breaks zope.app.testing:
Traceback (most recent call last):
File "/home/travis/build/mgedmin/zodbbrowser/src/zodbbrowser/ftests/test_standalone.py", line 23, in <module>
from zope.app.testing import setup
File "/home/travis/virtualenv/python2.7.14/lib/python2.7/site-packages/zope/app/testing/setup.py", line 59, in <module>
from zope.app.testing.placelesssetup import setUp as placelessSetUp
File "/home/travis/virtualenv/python2.7.14/lib/python2.7/site-packages/zope/app/testing/placelesssetup.py", line 32, in <module>
ContainerPlacelessSetup):
TypeError: Error when calling the metaclass bases
Cannot create a consistent method resolution
order (MRO) for bases PlacelessSetup, PlacelessSetup, PlacelessSetup, CleanUp
Downgrading zope.i18n to 4.2.0 makes the problem go away.
https://readthedocs.org/projects/zopei18n/ lags behind the GitHub repos, it seems the needed web hook is missing.
@jamadden @tseaver You are the developers at RTD, so could you please tap the magical button or add me (icemac
) as developer over there, too?
According to PyPI, python-gettext was last uploaded in February 2013. It's unclear whether the package is still supported. It doesn't --and isn't likely to-- exist in the Debian archive. But that's fine because its functionality can be reproduced well enough to pass the test suite with a replacement made of subprocess and msgfmt(1). We'll be using something like the following patch in Debian (it's not even worth writing a pull request ;)
--- a/src/zope/i18n/compile.py
+++ b/src/zope/i18n/compile.py
@@ -15,14 +15,17 @@
def compile_mo_file(domain, lc_messages_path):
"""Creates or updates a mo file in the locales folder."""
- if not HAS_PYTHON_GETTEXT:
- logger.critical("Unable to compile messages: Python `gettext` library missing.")
- return
-
base = join(lc_messages_path, domain)
pofile = str(base + '.po')
mofile = str(base + '.mo')
+ if not HAS_PYTHON_GETTEXT:
+ #logger.critical("Unable to compile messages: Python `gettext` library missing.")
+ # 2015-06-22 [email protected]: Fall back to msgfmt(1).
+ from subprocess import check_call
+ check_call(['msgfmt', '-o', mofile, pofile])
+ return
+
po_mtime = 0
try:
po_mtime = os.stat(pofile)[ST_MTIME]
In https://bugs.launchpad.net/zope.i18n/+bug/677650, @mgedmin reported:
I've a zope.schema.Date field in a z3c.form. It accepts dates like
11/20/10
but rejects dates like
11/20/2010
with an error of "The datetime string did not match the pattern u'M/d/yy'."
This is rather unfriendly; the date is clearly unambiguous and should be accepted.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.