summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Madden <jamadden@gmail.com>2017-12-16 07:40:29 -0600
committerJason Madden <jamadden@gmail.com>2017-12-16 07:40:29 -0600
commit89927bff938e8d11cd7c8acd705e8ebef43b6b1c (patch)
tree8373c827aa50a555ab210d183ee10f80f0884db8
parente924eea24f6d9b635a4b3370d90bb1ce7869b944 (diff)
downloadzope-i18n-drop-33.tar.gz
Remove _compat module and _u function in favor of native unicode literals and project gardeningdrop-33
- DRY with dependencies - Enable coveralls.io and add a coverage tox environment - A few tiny changes to increase coverage, but we're not at 100% - Enable testing sphinx docs for all versions - Publish CHANGES.rst on RTD - Modern tox.ini and .travis.yml - Travis was still testing 3.3 and not testing 3.6. - Remove 'level' qualifiers from XML parsing and ZCML test cases. They add about 2s to run the tests, but they're important; see #13. That extra time gets lost in the amount of time it takes to spin tox anyway.
-rw-r--r--.coveragerc11
-rw-r--r--.gitignore1
-rw-r--r--.travis.yml22
-rw-r--r--CHANGES.rst55
-rw-r--r--MANIFEST.in23
-rw-r--r--README.rst3
-rw-r--r--docs/api.rst25
-rw-r--r--docs/changelog.rst1
-rw-r--r--docs/conf.py14
-rw-r--r--docs/index.rst17
-rw-r--r--rtd.txt12
-rw-r--r--setup.cfg2
-rw-r--r--setup.py61
-rw-r--r--src/zope/i18n/__init__.py69
-rw-r--r--src/zope/i18n/_compat.py32
-rw-r--r--src/zope/i18n/format.py70
-rw-r--r--src/zope/i18n/gettextmessagecatalog.py5
-rw-r--r--src/zope/i18n/interfaces/__init__.py37
-rw-r--r--src/zope/i18n/interfaces/locales.py587
-rw-r--r--src/zope/i18n/locales/__init__.py84
-rw-r--r--src/zope/i18n/locales/fallbackcollator.txt15
-rw-r--r--src/zope/i18n/locales/tests/test_xmlfactory.py39
-rw-r--r--src/zope/i18n/locales/xmlfactory.py124
-rw-r--r--src/zope/i18n/simpletranslationdomain.py8
-rw-r--r--src/zope/i18n/testmessagecatalog.py7
-rw-r--r--src/zope/i18n/tests/locale3/en/LC_MESSAGES/zope-i18n.mobin315 -> 295 bytes
-rw-r--r--src/zope/i18n/tests/test_formats.py68
-rw-r--r--src/zope/i18n/tests/test_gettextmessagecatalog.py17
-rw-r--r--src/zope/i18n/tests/test_imessagecatalog.py6
-rw-r--r--src/zope/i18n/tests/test_itranslationdomain.py9
-rw-r--r--src/zope/i18n/tests/test_translationdomain.py62
-rw-r--r--src/zope/i18n/tests/test_zcml.py50
-rw-r--r--src/zope/i18n/translationdomain.py11
-rw-r--r--src/zope/i18n/zcml.py26
-rw-r--r--tox.ini34
35 files changed, 764 insertions, 843 deletions
diff --git a/.coveragerc b/.coveragerc
new file mode 100644
index 0000000..8dcbfb7
--- /dev/null
+++ b/.coveragerc
@@ -0,0 +1,11 @@
+[run]
+source = zope.i18n
+
+[report]
+precision = 2
+exclude_lines =
+ pragma: no cover
+ if __name__ == '__main__':
+ raise NotImplementedError
+ self.fail
+ raise AssertionError
diff --git a/.gitignore b/.gitignore
index bad6fe5..fec8ebe 100644
--- a/.gitignore
+++ b/.gitignore
@@ -15,3 +15,4 @@ docs/_build/
.coverage
coverage.xml
nosetests.xml
+htmlcov/
diff --git a/.travis.yml b/.travis.yml
index 37c5317..e770bda 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,15 +1,21 @@
language: python
sudo: false
python:
- - 2.7
- - 3.3
- - 3.4
- - 3.5
- - pypy
- - pypy3
+ - 2.7
+ - 3.4
+ - 3.5
+ - 3.6
+ - pypy
+ - pypy3
install:
- - pip install tox-travis
+ - pip install -U pip setuptools
+ - pip install -U coverage coveralls
+ - pip install -U -e .[test,docs]
script:
- - tox
+ - coverage run -m zope.testrunner --test-path=src
+ - coverage run -a -m sphinx -b doctest -d docs/_build/doctrees docs docs/_build/doctest
+after_success:
+ - coveralls
notifications:
email: false
+cache: pip
diff --git a/CHANGES.rst b/CHANGES.rst
index d6c62cb..314cf19 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -1,16 +1,19 @@
-=======
-CHANGES
-=======
+=========
+ CHANGES
+=========
4.2.1 (unreleased)
-------------------
+==================
- Ensure that all files are properly closed when compiling .mo files,
such as when the ``registerTranslations`` ZCML directive is used.
+- Remove the private ``_compat`` module and its utility function ``_u``
+ in favor of Unicode literals.
+
4.2.0 (2017-05-23)
-------------------
+==================
- Better error message on PO-File Syntax Errors. [SyZn]
@@ -29,20 +32,20 @@ CHANGES
4.1.0 (2015-11-06)
-------------------
+==================
- ``interpolate()`` now works recursively, if the mapping has a value which is
a ``zope.i18nmessageid.Message`` itself.
4.0.1 (2015-06-05)
---------------------
+==================
- Add support for Python 3.2 and PyPy3.
4.0.0 (2014-12-20)
---------------------
+==================
- Add support for testing with Travis.
@@ -50,7 +53,7 @@ CHANGES
4.0.0a4 (2013-02-18)
---------------------
+====================
- Restore zope.i18n.testing.{setUp,PlacelessSetup} that got lost in 4.0.0a3.
These require zope.publisher, which is not ported to Python 3 yet, so I
@@ -58,7 +61,7 @@ CHANGES
4.0.0a3 (2013-02-15)
---------------------
+====================
- Add support for Python 3.3.
@@ -71,7 +74,7 @@ CHANGES
3.8.0 (2012-03-15)
-------------------
+==================
- Add optional ``domain`` attribute to ``registerTranslations`` directive to
only load the specified translation domain. Allows to move catalogs to
@@ -85,18 +88,18 @@ CHANGES
3.7.4 (2010-07-08)
-------------------
+==================
- Add missing test dependency on ``zope.testing``.
3.7.3 (2010-04-30)
-------------------
+==================
- Remove of 'zope.testing.doctestunit' in favor of stdlib's 'doctest.
3.7.2 (2009-12-14)
-------------------
+==================
- It's a critical error when the ``GetText`` library is unavailable
and compilation is required.
@@ -107,7 +110,7 @@ CHANGES
version).
3.7.1 (2009-08-07)
-------------------
+==================
- Fix the interpackage translation domain merging feature to actually work.
We need to defer the merging into the ZCML handler execution phase, as the
@@ -122,7 +125,7 @@ CHANGES
3.7.0 (2009-03-18)
-------------------
+==================
- Update data to CLDR 1.1. This introduces contextual month
and day names and different month/day name widths. More CLDR updates
@@ -134,7 +137,7 @@ CHANGES
3.6.0 (2008-10-26)
-------------------
+==================
- Fix a test failure in the compile mo file support.
@@ -143,7 +146,7 @@ CHANGES
3.5.0 (2008-07-10)
-------------------
+==================
- Feature: Add new top-level negotiate function, which can be used to
negotiate the language when the available languages are set globally via
@@ -174,20 +177,20 @@ CHANGES
'1/1/20' for example.
3.4.0 (2007-10-02)
-------------------
+==================
- Update meta-data. No code changes.
3.4.0b5 (2007-08-15)
---------------------
+====================
- Bug: Fix dependency on ``zope.component`` to require it with the 'zcml'
extra instead of requiring ``zope.security`` directly.
3.4.0b4 (2007-07-19)
---------------------
+====================
- Bug: Number parsing was too forgiving, allowing non-numerical and/or
formatting characters before, after and within the number. The parsing is
@@ -195,7 +198,7 @@ CHANGES
3.4.0b3 (2007-06-28)
---------------------
+====================
- Bug: There was a bug in the parser that if no decimal place is given
you still had to type the decimal symbol. Corrected this problem (one
@@ -203,14 +206,14 @@ CHANGES
3.4.0b2 (2007-06-25)
---------------------
+====================
- Feature: Add ability to change the output type when parsing a
number.
3.4.0b1 (?)
------------
+===========
- Bug: Fix dependency on ``zope.security`` to require a version that
does not have the hidden dependency on ``zope.testing``.
@@ -221,7 +224,7 @@ packages. The changes can be reconstructed from the Zope 3 changelog.
3.2.0 (2006-01-05)
-------------------
+==================
- Corresponds to the verison of the zope.i18n package shipped as part of the
Zope 3.2.0 release.
@@ -238,7 +241,7 @@ packages. The changes can be reconstructed from the Zope 3 changelog.
3.0.0 (2004-11-07)
-------------------
+==================
- Corresponds to the version of the zope.i18n package shipped as part of
the Zope X3.0.0 release.
diff --git a/MANIFEST.in b/MANIFEST.in
index 5162988..ea5dc2b 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -1,4 +1,23 @@
-include *.txt *.rst *.py *.ini buildout.cfg .travis.yml
+include *.txt
+include *.rst
+include *.py
+include *.ini
+include buildout.cfg
+include .travis.yml
+include tox.ini
+include .coveragerc
recursive-include src *.txt *.py *.dtd *.xml *.html *.po *.mo *.in *.zcml
+recursive-include src *.py
+recursive-include src *.dtd
+recursive-include src *.xml
+recursive-include src *.html
+recursive-include src *.po
+recursive-include src *.mo
+recursive-include src *.in
+recursive-include src *.zcml
+
recursive-include src/zope/i18n/tests *.mo
-recursive-include docs *.rst *.py *.bat Makefile
+recursive-include docs *.rst
+recursive-include docs *.py
+recursive-include docs *.bat
+recursive-include docs Makefile
diff --git a/README.rst b/README.rst
index a021716..edba4f5 100644
--- a/README.rst
+++ b/README.rst
@@ -13,6 +13,9 @@ zope.i18n
.. image:: https://travis-ci.org/zopefoundation/zope.i18n.svg?branch=master
:target: https://travis-ci.org/zopefoundation/zope.i18n
+.. image:: https://coveralls.io/repos/github/zopefoundation/zope.i18n/badge.svg?branch=master
+ :target: https://coveralls.io/github/zopefoundation/zope.i18n?branch=master
+
.. image:: https://readthedocs.org/projects/zopeintid/badge/?version=latest
:target: http://zopeintid.readthedocs.io/en/latest/?badge=latest
:alt: Documentation Status
diff --git a/docs/api.rst b/docs/api.rst
index 6639431..706976e 100644
--- a/docs/api.rst
+++ b/docs/api.rst
@@ -1,5 +1,6 @@
-:mod:`zope.i18n` API Reference
-===============================
+=========================
+ zope.i18n API Reference
+=========================
.. testsetup::
@@ -7,37 +8,33 @@
from zope.i18n import translate
zope.i18n
----------
+=========
.. automodule:: zope.i18n
- :members:
zope.i18n.compile
------------------
+=================
.. automodule:: zope.i18n.compile
- :members:
zope.i18n.config
-----------------
+================
.. automodule:: zope.i18n.config
- :members:
zope.i18n.format
-----------------
+================
.. automodule:: zope.i18n.format
- :members:
zope.i18n.gettextmessagecatalog
--------------------------------
+===============================
.. automodule:: zope.i18n.gettextmessagecatalog
- :members:
zope.i18n.interfaces
---------------------
+====================
.. automodule:: zope.i18n.interfaces
- :members:
+
+.. automodule:: zope.i18n.interfaces.locales
diff --git a/docs/changelog.rst b/docs/changelog.rst
new file mode 100644
index 0000000..d9e113e
--- /dev/null
+++ b/docs/changelog.rst
@@ -0,0 +1 @@
+.. include:: ../CHANGES.rst
diff --git a/docs/conf.py b/docs/conf.py
index ecc5437..0ed66d4 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -11,7 +11,9 @@
# All configuration values have a default; values that are commented out
# serve to show the default.
-import sys, os, pkg_resources
+import sys
+import os
+import pkg_resources
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
@@ -29,6 +31,8 @@ extensions = [
'sphinx.ext.doctest',
'sphinx.ext.intersphinx',
'sphinx.ext.coverage',
+ 'sphinx.ext.viewcode',
+ 'repoze.sphinx.autointerface',
]
# Add any paths that contain templates here, relative to this directory.
@@ -45,7 +49,7 @@ master_doc = 'index'
# General information about the project.
project = u'zope.i18n'
-copyright = u'2010, Zope Foundation and Contributors'
+copyright = u'2010-2017, Zope Foundation and Contributors'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
@@ -74,7 +78,7 @@ release = rqmt.version
exclude_trees = ['_build']
# The reST default role (used for this markup: `text`) to use for all documents.
-#default_role = None
+default_role = 'obj'
# If true, '()' will be appended to :func: etc. cross-reference text.
#add_function_parentheses = True
@@ -203,3 +207,7 @@ latex_documents = [
# Example configuration for intersphinx: refer to the Python standard library.
intersphinx_mapping = {'http://docs.python.org/': None}
+
+autodoc_default_flags = ['members', 'show-inheritance']
+autoclass_content = 'both'
+autodoc_member_order = 'bysource'
diff --git a/docs/index.rst b/docs/index.rst
index 2ca2cc2..e8dbcf0 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -1,14 +1,5 @@
-:mod:`zope.18n` Documentation
-===============================
-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.
+.. include:: ../README.rst
Contents:
@@ -16,9 +7,11 @@ Contents:
:maxdepth: 2
api
+ changelog
-Indices and tables
-==================
+====================
+ Indices and tables
+====================
* :ref:`genindex`
* :ref:`modindex`
diff --git a/rtd.txt b/rtd.txt
index cce7b53..10cb7c4 100644
--- a/rtd.txt
+++ b/rtd.txt
@@ -1,11 +1 @@
-python-gettext
-pytz
-zope.component
-zope.configuration
-zope.i18nmessageid
-zope.location
-zope.proxy
-zope.schema
-zope.security
-zope.testing
-zope.testrunner
+.[compile,zcml,docs]
diff --git a/setup.cfg b/setup.cfg
new file mode 100644
index 0000000..2a9acf1
--- /dev/null
+++ b/setup.cfg
@@ -0,0 +1,2 @@
+[bdist_wheel]
+universal = 1
diff --git a/setup.py b/setup.py
index 64951c6..1317d2b 100644
--- a/setup.py
+++ b/setup.py
@@ -22,11 +22,10 @@ import os
from setuptools import setup, find_packages
def read(*rnames):
- text = open(os.path.join(os.path.dirname(__file__), *rnames)).read()
- return text
+ with open(os.path.join(os.path.dirname(__file__), *rnames)) as f:
+ return f.read()
def alltests():
- import os
import sys
import unittest
# use the zope.testrunner machinery to find all the
@@ -40,6 +39,21 @@ def alltests():
suites = list(zope.testrunner.find.find_suites(options))
return unittest.TestSuite(suites)
+COMPILE_REQUIRES = [
+ 'python-gettext'
+]
+
+ZCML_REQUIRES = [
+ 'zope.component[zcml]',
+ 'zope.configuration',
+ 'zope.security',
+]
+
+TESTS_REQUIRE = COMPILE_REQUIRES + ZCML_REQUIRES + [
+ 'zope.testing',
+ 'zope.testrunner',
+]
+
setup(
name='zope.i18n',
version='4.2.1.dev0',
@@ -50,7 +64,7 @@ setup(
read('README.rst')
+ '\n\n' +
read('CHANGES.rst')
- ),
+ ),
license='ZPL 2.1',
keywords=('zope3 internationalization localization i18n l10n '
'gettext ICU locale'),
@@ -71,7 +85,8 @@ setup(
'Natural Language :: English',
'Operating System :: OS Independent',
'Topic :: Internet :: WWW/HTTP',
- 'Framework :: Zope3'],
+ 'Framework :: Zope3',
+ ],
url='https://github.com/zopefoundation/zope.i18n',
packages=find_packages('src'),
package_dir={'': 'src'},
@@ -82,32 +97,18 @@ setup(
'zope.schema',
'zope.i18nmessageid',
'zope.component',
+ ],
+ extras_require={
+ 'test': TESTS_REQUIRE,
+ 'compile': COMPILE_REQUIRES,
+ 'zcml': ZCML_REQUIRES,
+ 'docs': [
+ 'Sphinx',
+ 'repoze.sphinx.autointerface',
],
- extras_require=dict(
- test=[
- 'python-gettext',
- 'zope.component [zcml]',
- 'zope.configuration',
- 'zope.security',
- 'zope.testing',
- 'zope.testrunner',
- ],
- compile=['python-gettext'],
- zcml=[
- 'zope.component [zcml]',
- 'zope.configuration',
- 'zope.security',
- ],
- ),
- tests_require = [
- 'python-gettext',
- 'zope.component [zcml]',
- 'zope.configuration',
- 'zope.security',
- 'zope.testing',
- 'zope.testrunner',
- ],
- test_suite = '__main__.alltests',
+ },
+ tests_require=TESTS_REQUIRE,
+ test_suite='__main__.alltests',
include_package_data=True,
zip_safe=False,
)
diff --git a/src/zope/i18n/__init__.py b/src/zope/i18n/__init__.py
index 7377ecc..97d0e4c 100644
--- a/src/zope/i18n/__init__.py
+++ b/src/zope/i18n/__init__.py
@@ -24,11 +24,7 @@ from zope.i18n.interfaces import INegotiator
from zope.i18n.interfaces import ITranslationDomain
from zope.i18n.interfaces import IFallbackTranslationDomainFactory
-from ._compat import _u
-
-PY3 = sys.version_info[0] == 3
-if PY3:
- unicode = str
+text_type = str if bytes is not str else unicode
# Set up regular expressions for finding interpolation variables in text.
# NAME_RE must exactly match the expression of the same name in the
@@ -36,7 +32,7 @@ if PY3:
NAME_RE = r"[a-zA-Z_][-a-zA-Z0-9_]*"
_interp_regex = re.compile(r'(?<!\$)(\$(?:(%(n)s)|{(%(n)s)}))'
- % ({'n': NAME_RE}))
+ % ({'n': NAME_RE}))
def negotiate(context):
@@ -52,7 +48,7 @@ def negotiate(context):
return None
def translate(msgid, domain=None, mapping=None, context=None,
- target_language=None, default=None):
+ target_language=None, default=None):
"""Translate text.
First setup some test components:
@@ -71,26 +67,26 @@ def translate(msgid, domain=None, mapping=None, context=None,
Normally, the translation system will use a domain utility:
- >>> component.provideUtility(TestDomain(eek=_u("ook")), name='my.domain')
- >>> translate(_u("eek"), 'my.domain')
- u'ook'
+ >>> component.provideUtility(TestDomain(eek=u"ook"), name='my.domain')
+ >>> print(translate(u"eek", 'my.domain'))
+ ook
Normally, if no domain is given, or if there is no domain utility
for the given domain, then the text isn't translated:
- >>> translate(_u("eek"))
- u'eek'
+ >>> print(translate(u"eek"))
+ eek
Moreover the text will be converted to unicode:
- >>> translate('eek', 'your.domain')
- u'eek'
+ >>> print(translate('eek', 'your.domain'))
+ eek
A fallback domain factory can be provided. This is normally used
for testing:
- >>> def fallback(domain=_u("")):
- ... return TestDomain(eek=_u("test-from-") + domain)
+ >>> def fallback(domain=u""):
+ ... return TestDomain(eek=u"test-from-" + domain)
>>> interface.directlyProvides(
... fallback,
... zope.i18n.interfaces.IFallbackTranslationDomainFactory,
@@ -98,11 +94,11 @@ def translate(msgid, domain=None, mapping=None, context=None,
>>> component.provideUtility(fallback)
- >>> translate(_u("eek"))
- u'test-from-'
+ >>> print(translate(u"eek"))
+ test-from-
- >>> translate(_u("eek"), 'your.domain')
- u'test-from-your.domain'
+ >>> print(translate(u"eek", 'your.domain'))
+ test-from-your.domain
"""
if isinstance(msgid, Message):
@@ -111,7 +107,7 @@ def translate(msgid, domain=None, mapping=None, context=None,
mapping = msgid.mapping
if default is None:
- default = unicode(msgid)
+ default = text_type(msgid)
if domain:
util = queryUtility(ITranslationDomain, domain)
@@ -141,33 +137,32 @@ def interpolate(text, mapping=None):
In the text we can use substitution slots like $varname or ${varname}:
- >>> from zope.i18n._compat import _u
- >>> interpolate(_u("This is $name version ${version}."), mapping)
- u'This is Zope version 3.'
+ >>> print(interpolate(u"This is $name version ${version}.", mapping))
+ This is Zope version 3.
Interpolation variables can be used more than once in the text:
- >>> interpolate(_u("This is $name version ${version}. ${name} $version!"),
- ... mapping)
- u'This is Zope version 3. Zope 3!'
+ >>> print(interpolate(u"This is $name version ${version}. ${name} $version!",
+ ... mapping))
+ This is Zope version 3. Zope 3!
In case if the variable wasn't found in the mapping or '$$' form
was used no substitution will happens:
- >>> interpolate(_u("This is $name $version. $unknown $$name $${version}."),
- ... mapping)
- u'This is Zope 3. $unknown $$name $${version}.'
+ >>> print(interpolate(u"This is $name $version. $unknown $$name $${version}.",
+ ... mapping))
+ This is Zope 3. $unknown $$name $${version}.
- >>> interpolate(_u("This is ${name}"))
- u'This is ${name}'
+ >>> print(interpolate(u"This is ${name}"))
+ This is ${name}
If a mapping value is a message id itself it is interpolated, too:
>>> from zope.i18nmessageid import Message
- >>> interpolate(_u("This is $meta."),
- ... mapping={'meta': Message(_u("$name $version"),
- ... mapping=mapping)})
- u'This is Zope 3.'
+ >>> print(interpolate(u"This is $meta.",
+ ... mapping={'meta': Message(u"$name $version",
+ ... mapping=mapping)}))
+ This is Zope 3.
"""
def replace(match):
@@ -175,7 +170,7 @@ def interpolate(text, mapping=None):
value = mapping.get(param1 or param2, whole)
if isinstance(value, Message):
value = interpolate(value, value.mapping)
- return unicode(value)
+ return text_type(value)
if not text or not mapping:
return text
diff --git a/src/zope/i18n/_compat.py b/src/zope/i18n/_compat.py
deleted file mode 100644
index 09b3f74..0000000
--- a/src/zope/i18n/_compat.py
+++ /dev/null
@@ -1,32 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2015 Zope Foundation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE
-#
-##############################################################################
-import sys
-
-if sys.version_info[0] < 3: #pragma NO COVER Python2
-
- PY2 = True
- PY3 = False
-
- def _u(s, encoding='unicode_escape'):
- return unicode(s, encoding)
-
-else: #pragma NO COVER Python3
-
- PY2 = False
- PY3 = True
-
- def _u(s, encoding=None):
- if encoding is None:
- return s
- return str(s, encoding)
diff --git a/src/zope/i18n/format.py b/src/zope/i18n/format.py
index 494d09c..0c1ffd6 100644
--- a/src/zope/i18n/format.py
+++ b/src/zope/i18n/format.py
@@ -26,14 +26,12 @@ import pytz.reference
from zope.i18n.interfaces import IDateTimeFormat, INumberFormat
from zope.interface import implementer
-from ._compat import _u
-
-PY3 = sys.version_info[0] == 3
-if PY3:
- unicode = str
- NATIVE_NUMBER_TYPES = (int, float)
-else:
- NATIVE_NUMBER_TYPES = (int, float, long)
+text_type = str if bytes is not str else unicode
+NATIVE_NUMBER_TYPES = (int, float)
+try:
+ NATIVE_NUMBER_TYPES += (long,)
+except NameError:
+ pass # Py3
def roundHalfUp(n):
"""Works like round() in python2.x
@@ -134,7 +132,7 @@ class DateTimeFormat(object):
ampm_entry = _findFormattingCharacterInPattern('a', bin_pattern)
if not ampm_entry:
raise DateTimeParseError(
- 'Cannot handle 12-hour format without am/pm marker.')
+ 'Cannot handle 12-hour format without am/pm marker.')
ampm = self.calendar.pm == results[bin_pattern.index(ampm_entry[0])]
if hour == 12:
ampm = not ampm
@@ -142,9 +140,10 @@ class DateTimeFormat(object):
# Shortcut for the simple int functions
dt_fields_map = {'d': 2, 'H': 3, 'm': 4, 's': 5, 'S': 6}
- for field in dt_fields_map.keys():
+ for field in dt_fields_map:
entry = _findFormattingCharacterInPattern(field, bin_pattern)
- if not entry: continue
+ if not entry:
+ continue
pos = dt_fields_map[field]
ordered[pos] = int(results[bin_pattern.index(entry[0])])
@@ -204,7 +203,7 @@ class DateTimeFormat(object):
else:
bin_pattern = self._bin_pattern
- text = _u("")
+ text = u""
info = buildDateTimeInfo(obj, self.calendar, bin_pattern)
for elem in bin_pattern:
text += info.get(elem, elem)
@@ -227,18 +226,19 @@ class NumberFormat(object):
def __init__(self, pattern=None, symbols={}):
# setup default symbols
self.symbols = {
- _u("decimal"): _u("."),
- _u("group"): _u(","),
- _u("list"): _u(";"),
- _u("percentSign"): _u("%"),
- _u("nativeZeroDigit"): _u("0"),
- _u("patternDigit"): _u("#"),
- _u("plusSign"): _u("+"),
- _u("minusSign"): _u("-"),
- _u("exponential"): _u("E"),
- _u("perMille"): _u("\xe2\x88\x9e"),
- _u("infinity"): _u("\xef\xbf\xbd"),
- _u("nan"): '' }
+ u"decimal": u".",
+ u"group": u",",
+ u"list": u";",
+ u"percentSign": u"%",
+ u"nativeZeroDigit": u"0",
+ u"patternDigit": u"#",
+ u"plusSign": u"+",
+ u"minusSign": u"-",
+ u"exponential": u"E",
+ u"perMille": u"\xe2\x88\x9e",
+ u"infinity": u"\xef\xbf\xbd",
+ u"nan": u''
+ }
self.symbols.update(symbols)
self._pattern = pattern
self._bin_pattern = None
@@ -396,7 +396,7 @@ class NumberFormat(object):
# The exponential might have a mandatory sign; remove it from the
# bin_pattern and remember the setting
exp_bin_pattern = bin_pattern[EXPONENTIAL]
- plus_sign = _u("")
+ plus_sign = u""
if exp_bin_pattern.startswith('+'):
plus_sign = self.symbols['plusSign']
exp_bin_pattern = exp_bin_pattern[1:]
@@ -480,7 +480,7 @@ class NumberFormat(object):
text += bin_pattern[PADDING4]*post_padding
# TODO: Need to make sure unicode is everywhere
- return unicode(text)
+ return text_type(text)
@@ -667,8 +667,8 @@ def buildDateTimeInfo(dt, calendar, pattern):
tz_name = tzinfo.tzname(dt) or tz_defaultname
tz_fullname = getattr(tzinfo, 'zone', None) or tz_name
- info = {('y', 2): unicode(dt.year)[2:],
- ('y', 4): unicode(dt.year),
+ info = {('y', 2): text_type(dt.year)[2:],
+ ('y', 4): text_type(dt.year),
}
# Generic Numbers
@@ -679,7 +679,7 @@ def buildDateTimeInfo(dt, calendar, pattern):
('S', dt.microsecond), ('w', int(dt.strftime('%W'))),
('W', week_in_month)):
for entry in _findFormattingCharacterInPattern(field, pattern):
- info[entry] = (_u("%%.%ii") %entry[1]) %value
+ info[entry] = (u"%%.%ii" %entry[1]) %value
# am/pm marker (Text)
for entry in _findFormattingCharacterInPattern('a', pattern):
@@ -693,9 +693,9 @@ def buildDateTimeInfo(dt, calendar, pattern):
# time zone (Text)
for entry in _findFormattingCharacterInPattern('z', pattern):
if entry[1] == 1:
- info[entry] = _u("%s%i%.2i") %(tz_sign, tz_hours, tz_mins)
+ info[entry] = u"%s%i%.2i" %(tz_sign, tz_hours, tz_mins)
elif entry[1] == 2:
- info[entry] = _u("%s%.2i:%.2i") %(tz_sign, tz_hours, tz_mins)
+ info[entry] = u"%s%.2i:%.2i" %(tz_sign, tz_hours, tz_mins)
elif entry[1] == 3:
info[entry] = tz_name
else:
@@ -704,9 +704,9 @@ def buildDateTimeInfo(dt, calendar, pattern):
# month in year (Text and Number)
for entry in _findFormattingCharacterInPattern('M', pattern):
if entry[1] == 1:
- info[entry] = _u("%i") %dt.month
+ info[entry] = u"%i" %dt.month
elif entry[1] == 2:
- info[entry] = _u("%.2i") %dt.month
+ info[entry] = u"%.2i" %dt.month
elif entry[1] == 3:
info[entry] = calendar.months[dt.month][1]
else:
@@ -715,9 +715,9 @@ def buildDateTimeInfo(dt, calendar, pattern):
# day in week (Text and Number)
for entry in _findFormattingCharacterInPattern('E', pattern):
if entry[1] == 1:
- info[entry] = _u("%i") %weekday
+ info[entry] = u"%i" % weekday
elif entry[1] == 2:
- info[entry] = _u("%.2i") %weekday
+ info[entry] = u"%.2i" % weekday
elif entry[1] == 3:
info[entry] = calendar.days[dt.weekday() + 1][1]
else:
diff --git a/src/zope/i18n/gettextmessagecatalog.py b/src/zope/i18n/gettextmessagecatalog.py
index 1376d11..f18f6f9 100644
--- a/src/zope/i18n/gettextmessagecatalog.py
+++ b/src/zope/i18n/gettextmessagecatalog.py
@@ -44,11 +44,8 @@ class GettextMessageCatalog(object):
def reload(self):
'See IMessageCatalog'
- fp = open(self._path_to_file, 'rb')
- try:
+ with open(self._path_to_file, 'rb') as fp:
self._catalog = GNUTranslations(fp)
- finally:
- fp.close()
def getMessage(self, id):
'See IMessageCatalog'
diff --git a/src/zope/i18n/interfaces/__init__.py b/src/zope/i18n/interfaces/__init__.py
index 9cee5c6..397c8f5 100644
--- a/src/zope/i18n/interfaces/__init__.py
+++ b/src/zope/i18n/interfaces/__init__.py
@@ -16,7 +16,6 @@
from zope.interface import Interface, Attribute
from zope.schema import TextLine, Dict, Choice, Field
-from .._compat import _u
class II18nAware(Interface):
"""Internationalization aware content object."""
@@ -69,13 +68,13 @@ class IMessageCatalog(Interface):
"""
language = TextLine(
- title=_u("Language"),
- description=_u("The language the catalog translates to."),
+ title=u"Language",
+ description=u"The language the catalog translates to.",
required=True)
domain = TextLine(
- title=_u("Domain"),
- description=_u("The domain the catalog is registered for."),
+ title=u"Domain",
+ description=u"The domain the catalog is registered for.",
required=True)
def getIdentifier():
@@ -129,8 +128,8 @@ class ITranslationDomain(Interface):
"""
domain = TextLine(
- title=_u("Domain Name"),
- description=_u("The name of the domain this object represents."),
+ title=u"Domain Name",
+ description=u"The name of the domain this object represents.",
required=True)
def translate(msgid, mapping=None, context=None, target_language=None,
@@ -155,7 +154,7 @@ class IFallbackTranslationDomainFactory(Interface):
debugging i18n.
"""
- def __call__(domain_id=_u("")):
+ def __call__(domain_id=u""):
"""Return a fallback translation domain for the given domain id.
"""
@@ -357,22 +356,22 @@ class INumberFormat(IFormat):
"""
type = Field(
- title=_u("Type"),
- description=(_u("The type into which a string is parsed. If ``None``, "
- "then ``int`` will be used for whole numbers and "
- "``float`` for decimals.")),
+ title=u"Type",
+ description=((u"The type into which a string is parsed. If ``None``, "
+ u"then ``int`` will be used for whole numbers and "
+ u"``float`` for decimals.")),
default=None,
required=False)
symbols = Dict(
- title=_u("Number Symbols"),
+ title=u"Number Symbols",
key_type=Choice(
- title=_u("Dictionary Class"),
- values=(_u("decimal"), _u("group"), _u("list"), _u("percentSign"),
- _u("nativeZeroDigit"), _u("patternDigit"), _u("plusSign"),
- _u("minusSign"), _u("exponential"), _u("perMille"),
- _u("infinity"), _u("nan"))),
- value_type=TextLine(title=_u("Symbol")))
+ title=u"Dictionary Class",
+ values=(u"decimal", u"group", u"list", u"percentSign",
+ u"nativeZeroDigit", u"patternDigit", u"plusSign",
+ u"minusSign", u"exponential", u"perMille",
+ u"infinity", u"nan")),
+ value_type=TextLine(title=u"Symbol"))
class IDateTimeFormat(IFormat):
diff --git a/src/zope/i18n/interfaces/locales.py b/src/zope/i18n/interfaces/locales.py
index 25d64de..f6017ad 100644
--- a/src/zope/i18n/interfaces/locales.py
+++ b/src/zope/i18n/interfaces/locales.py
@@ -13,12 +13,13 @@
##############################################################################
"""Interfaces related to Locales
"""
+import datetime
import re
from zope.interface import Interface, Attribute
from zope.schema import \
Field, Text, TextLine, Int, Bool, Tuple, List, Dict, Date
-from zope.schema import Container, Choice
-from .._compat import _u
+from zope.schema import Choice
+
class ILocaleProvider(Interface):
"""This interface is our connection to the Zope 3 service. From it
@@ -65,36 +66,36 @@ class ILocaleIdentity(Interface):
"""
language = TextLine(
- title = _u("Language Type"),
- description = _u("The language for which a locale is applicable."),
- constraint = re.compile(r'[a-z]{2}').match,
- required = True,
- readonly = True)
+ title=u"Language Type",
+ description=u"The language for which a locale is applicable.",
+ constraint=re.compile(r'[a-z]{2}').match,
+ required=True,
+ readonly=True)
script = TextLine(
- title = _u("Script Type"),
- description = _u("""The script for which the language/locale is
+ title=u"Script Type",
+ description=(u"""The script for which the language/locale is
applicable."""),
- constraint = re.compile(r'[a-z]*').match)
+ constraint=re.compile(r'[a-z]*').match)
territory = TextLine(
- title = _u("Territory Type"),
- description = _u("The territory for which a locale is applicable."),
- constraint = re.compile(r'[A-Z]{2}').match,
- required = True,
- readonly = True)
+ title=u"Territory Type",
+ description=u"The territory for which a locale is applicable.",
+ constraint=re.compile(r'[A-Z]{2}').match,
+ required=True,
+ readonly=True)
variant = TextLine(
- title = _u("Variant Type"),
- description = _u("The variant for which a locale is applicable."),
- constraint = re.compile(r'[a-zA-Z]*').match,
- required = True,
- readonly = True)
+ title=u"Variant Type",
+ description=u"The variant for which a locale is applicable.",
+ constraint=re.compile(r'[a-zA-Z]*').match,
+ required=True,
+ readonly=True)
version = Field(
- title = _u("Locale Version"),
- description = _u("The value of this field is an ILocaleVersion object."),
- readonly = True)
+ title=u"Locale Version",
+ description=u"The value of this field is an ILocaleVersion object.",
+ readonly=True)
def __repr__(self):
"""Defines the representation of the id, which should be a compact
@@ -108,22 +109,22 @@ class ILocaleVersion(Interface):
"""
number = TextLine(
- title = _u("Version Number"),
- description = _u("The version number of the locale."),
- constraint = re.compile(r'^([0-9].)*[0-9]$').match,
- required = True,
- readonly = True)
+ title=u"Version Number",
+ description=u"The version number of the locale.",
+ constraint=re.compile(r'^([0-9].)*[0-9]$').match,
+ required=True,
+ readonly=True)
generationDate = Date(
- title = _u("Generation Date"),
- description = _u("Specifies the creation date of the locale."),
- constraint = lambda date: date < datetime.now(),
- readonly = True)
+ title=u"Generation Date",
+ description=u"Specifies the creation date of the locale.",
+ constraint=lambda date: date < datetime.datetime.now(),
+ readonly=True)
notes = Text(
- title = _u("Notes"),
- description = _u("Some release notes for the version of this locale."),
- readonly = True)
+ title=u"Notes",
+ description=u"Some release notes for the version of this locale.",
+ readonly=True)
class ILocaleDisplayNames(Interface):
@@ -135,34 +136,34 @@ class ILocaleDisplayNames(Interface):
"""
languages = Dict(
- title = _u("Language type to translated name"),
- key_type = TextLine(title=_u("Language Type")),
- value_type = TextLine(title=_u("Language Name")))
+ title=u"Language type to translated name",
+ key_type=TextLine(title=u"Language Type"),
+ value_type=TextLine(title=u"Language Name"))
scripts = Dict(
- title = _u("Script type to script name"),
- key_type = TextLine(title=_u("Script Type")),
- value_type = TextLine(title=_u("Script Name")))
+ title=u"Script type to script name",
+ key_type=TextLine(title=u"Script Type"),
+ value_type=TextLine(title=u"Script Name"))
territories = Dict(
- title = _u("Territory type to translated territory name"),
- key_type = TextLine(title=_u("Territory Type")),
- value_type = TextLine(title=_u("Territory Name")))
+ title=u"Territory type to translated territory name",
+ key_type=TextLine(title=u"Territory Type"),
+ value_type=TextLine(title=u"Territory Name"))
variants = Dict(
- title = _u("Variant type to name"),
- key_type = TextLine(title=_u("Variant Type")),
- value_type = TextLine(title=_u("Variant Name")))
+ title=u"Variant type to name",
+ key_type=TextLine(title=u"Variant Type"),
+ value_type=TextLine(title=u"Variant Name"))
keys = Dict(
- title = _u("Key type to name"),
- key_type = TextLine(title=_u("Key Type")),
- value_type = TextLine(title=_u("Key Name")))
+ title=u"Key type to name",
+ key_type=TextLine(title=u"Key Type"),
+ value_type=TextLine(title=u"Key Name"))
types = Dict(
- title = _u("Type type and key to localized name"),
- key_type = Tuple(title=_u("Type Type and Key")),
- value_type = TextLine(title=_u("Type Name")))
+ title=u"Type type and key to localized name",
+ key_type=Tuple(title=u"Type Type and Key"),
+ value_type=TextLine(title=u"Type Name"))
class ILocaleTimeZone(Interface):
@@ -175,128 +176,128 @@ class ILocaleTimeZone(Interface):
"""
type = TextLine(
- title = _u("Time Zone Type"),
- description = _u("Standard name of the timezone for unique referencing."),
- required = True,
- readonly = True)
+ title=u"Time Zone Type",
+ description=u"Standard name of the timezone for unique referencing.",
+ required=True,
+ readonly=True)
cities = List(
- title = _u("Cities"),
- description = _u("Cities in Timezone"),
- value_type = TextLine(title=_u("City Name")),
- required = True,
- readonly = True)
+ title=u"Cities",
+ description=u"Cities in Timezone",
+ value_type=TextLine(title=u"City Name"),
+ required=True,
+ readonly=True)
names = Dict(
- title = _u("Time Zone Names"),
- description = _u("Various names of the timezone."),
- key_type = Choice(
- title = _u("Time Zone Name Type"),
- values = (_u("generic"), _u("standard"), _u("daylight"))),
- value_type = Tuple(title=_u("Time Zone Name and Abbreviation"),
- min_length=2, max_length=2),
- required = True,
- readonly = True)
+ title=u"Time Zone Names",
+ description=u"Various names of the timezone.",
+ key_type=Choice(
+ title=u"Time Zone Name Type",
+ values=(u"generic", u"standard", u"daylight")),
+ value_type=Tuple(title=u"Time Zone Name and Abbreviation",
+ min_length=2, max_length=2),
+ required=True,
+ readonly=True)
class ILocaleFormat(Interface):
"""Specifies a format for a particular type of data."""
type = TextLine(
- title=_u("Format Type"),
- description=_u("The name of the format"),
- required = False,
- readonly = True)
+ title=u"Format Type",
+ description=u"The name of the format",
+ required=False,
+ readonly=True)
displayName = TextLine(
- title = _u("Display Name"),
- description = _u("Name of the calendar, for example 'gregorian'."),
- required = False,
- readonly = True)
+ title=u"Display Name",
+ description=u"Name of the calendar, for example 'gregorian'.",
+ required=False,
+ readonly=True)
pattern = TextLine(
- title = _u("Format Pattern"),
- description = _u("The pattern that is used to format the object."),
- required = True,
- readonly = True)
+ title=u"Format Pattern",
+ description=u"The pattern that is used to format the object.",
+ required=True,
+ readonly=True)
class ILocaleFormatLength(Interface):
"""The format length describes a class of formats."""
type = Choice(
- title = _u("Format Length Type"),
- description = _u("Name of the format length"),
- values = (_u("full"), _u("long"), _u("medium"), _u("short"))
+ title=u"Format Length Type",
+ description=u"Name of the format length",
+ values=(u"full", u"long", u"medium", u"short")
)
default = TextLine(
- title=_u("Default Format"),
- description=_u("The name of the defaulkt format."))
+ title=u"Default Format",
+ description=u"The name of the defaulkt format.")
formats = Dict(
- title = _u("Formats"),
- description = _u("Maps format types to format objects"),
- key_type = TextLine(title = _u("Format Type")),
- value_type = Field(
- title = _u("Format Object"),
- description = _u("Values are ILocaleFormat objects.")),
- required = True,
- readonly = True)
+ title=u"Formats",
+ description=u"Maps format types to format objects",
+ key_type=TextLine(title=u"Format Type"),
+ value_type=Field(
+ title=u"Format Object",
+ description=u"Values are ILocaleFormat objects."),
+ required=True,
+ readonly=True)
class ILocaleMonthContext(Interface):
"""Specifices a usage context for month names"""
type = TextLine(
- title=_u("Month context type"),
- description=_u("Name of the month context, format or stand-alone."))
+ title=u"Month context type",
+ description=u"Name of the month context, format or stand-alone.")
defaultWidth = TextLine(
- title=_u("Default month name width"),
- default=_u("wide"))
+ title=u"Default month name width",
+ default=u"wide")
months = Dict(
- title=_u("Month Names"),
- description=_u("A mapping of month name widths to a mapping of"
- "corresponding month names."),
+ title=u"Month Names",
+ description=(u"A mapping of month name widths to a mapping of"
+ u"corresponding month names."),
key_type=Choice(
- title=_u("Width type"),
- values=(_u("wide"), _u("abbreviated"), _u("narrow"))),
+ title=u"Width type",
+ values=(u"wide", u"abbreviated", u"narrow")),
value_type=Dict(
- title=_u("Month name"),
- key_type=Int(title=_u("Type"), min=1, max=12),
- value_type=TextLine(title=_u("Month Name")))
- )
+ title=u"Month name",
+ key_type=Int(title=u"Type", min=1, max=12),
+ value_type=TextLine(title=u"Month Name"))
+ )
class ILocaleDayContext(Interface):
"""Specifices a usage context for days names"""
type = TextLine(
- title=_u("Day context type"),
- description=_u("Name of the day context, format or stand-alone."))
+ title=u"Day context type",
+ description=u"Name of the day context, format or stand-alone.")
defaultWidth = TextLine(
- title=_u("Default day name width"),
- default=_u("wide"))
+ title=u"Default day name width",
+ default=u"wide")
days = Dict(
- title=_u("Day Names"),
- description=_u("A mapping of day name widths to a mapping of"
- "corresponding day names."),
+ title=u"Day Names",
+ description=(u"A mapping of day name widths to a mapping of"
+ u"corresponding day names."),
key_type=Choice(
- title=_u("Width type"),
- values=(_u("wide"), _u("abbreviated"), _u("narrow"))),
+ title=u"Width type",
+ values=(u"wide", u"abbreviated", u"narrow")),
value_type=Dict(
- title=_u("Day name"),
+ title=u"Day name",
key_type=Choice(
- title=_u("Type"),
- values=(_u("sun"), _u("mon"), _u("tue"), _u("wed"),
- _u("thu"), _u("fri"), _u("sat"))),
- value_type=TextLine(title=_u("Day Name")))
- )
+ title=u"Type",
+ values=(u"sun", u"mon", u"tue", u"wed",
+ u"thu", u"fri", u"sat")),
+ value_type=TextLine(title=u"Day Name"))
+ )
class ILocaleCalendar(Interface):
@@ -304,57 +305,57 @@ class ILocaleCalendar(Interface):
which made it attractive to be added."""
type = TextLine(
- title=_u("Calendar Type"),
- description=_u("Name of the calendar, for example 'gregorian'."))
+ title=u"Calendar Type",
+ description=u"Name of the calendar, for example 'gregorian'.")
defaultMonthContext = TextLine(
- title=_u("Default month context"),
- default=_u("format"))
+ title=u"Default month context",
+ default=u"format")
monthContexts = Dict(
- title=_u("Month Contexts"),
- description=_u("A mapping of month context types to "
- "ILocaleMonthContext objects"),
- key_type=Choice(title=_u("Type"),
- values=(_u("format"), _u("stand-alone"))),
- value_type=Field(title=_u("ILocaleMonthContext object")))
+ title=u"Month Contexts",
+ description=(u"A mapping of month context types to "
+ u"ILocaleMonthContext objects"),
+ key_type=Choice(title=u"Type",
+ values=(u"format", u"stand-alone")),
+ value_type=Field(title=u"ILocaleMonthContext object"))
# BBB: leftover from CLDR 1.0
months = Dict(
- title = _u("Month Names"),
- description = _u("A mapping of all month names and abbreviations"),
- key_type = Int(title=_u("Type"), min=1, max=12),
- value_type = Tuple(title=_u("Month Name and Abbreviation"),
- min_length=2, max_length=2))
+ title=u"Month Names",
+ description=u"A mapping of all month names and abbreviations",
+ key_type=Int(title=u"Type", min=1, max=12),
+ value_type=Tuple(title=u"Month Name and Abbreviation",
+ min_length=2, max_length=2))
defaultDayContext = TextLine(
- title=_u("Default day context"),
- default=_u("format"))
+ title=u"Default day context",
+ default=u"format")
dayContexts = Dict(
- title=_u("Day Contexts"),
- description=_u("A mapping of day context types to "
- "ILocaleDayContext objects"),
- key_type=Choice(title=_u("Type"),
- values=(_u("format"), _u("stand-alone"))),
- value_type=Field(title=_u("ILocaleDayContext object")))
+ title=u"Day Contexts",
+ description=(u"A mapping of day context types to "
+ u"ILocaleDayContext objects"),
+ key_type=Choice(title=u"Type",
+ values=(u"format", u"stand-alone")),
+ value_type=Field(title=u"ILocaleDayContext object"))
# BBB: leftover from CLDR 1.0
days = Dict(
- title=_u("Weekdays Names"),
- description = _u("A mapping of all month names and abbreviations"),
- key_type = Choice(title=_u("Type"),
- values=(_u("sun"), _u("mon"), _u("tue"), _u("wed"),
- _u("thu"), _u("fri"), _u("sat"))),
- value_type = Tuple(title=_u("Weekdays Name and Abbreviation"),
- min_length=2, max_length=2))
+ title=u"Weekdays Names",
+ description=u"A mapping of all month names and abbreviations",
+ key_type=Choice(title=u"Type",
+ values=(u"sun", u"mon", u"tue", u"wed",
+ u"thu", u"fri", u"sat")),
+ value_type=Tuple(title=u"Weekdays Name and Abbreviation",
+ min_length=2, max_length=2))
week = Dict(
- title=_u("Week Information"),
- description = _u("Contains various week information"),
- key_type = Choice(
- title=_u("Type"),
- description=_u("""
+ title=u"Week Information",
+ description=u"Contains various week information",
+ key_type=Choice(
+ title=u"Type",
+ description=(u"""
Varies Week information:
- 'minDays' is just an integer between 1 and 7.
@@ -364,51 +365,51 @@ class ILocaleCalendar(Interface):
- The 'weekendStart' and 'weekendEnd' are tuples of the form
(weekDayNumber, datetime.time)
"""),
- values=(_u("minDays"), _u("firstDay"),
- _u("weekendStart"), _u("weekendEnd"))))
+ values=(u"minDays", u"firstDay",
+ u"weekendStart", u"weekendEnd")))
- am = TextLine(title=_u("AM String"))
+ am = TextLine(title=u"AM String")
- pm = TextLine(title=_u("PM String"))
+ pm = TextLine(title=u"PM String")
eras = Dict(
- title = _u("Era Names"),
- key_type = Int(title=_u("Type"), min=0),
- value_type = Tuple(title=_u("Era Name and Abbreviation"),
- min_length=2, max_length=2))
+ title=u"Era Names",
+ key_type=Int(title=u"Type", min=0),
+ value_type=Tuple(title=u"Era Name and Abbreviation",
+ min_length=2, max_length=2))
- defaultDateFormat = TextLine(title=_u("Default Date Format Type"))
+ defaultDateFormat = TextLine(title=u"Default Date Format Type")
dateFormats = Dict(
- title=_u("Date Formats"),
- description = _u("Contains various Date Formats."),
- key_type = Choice(
- title=_u("Type"),
- description = _u("Name of the format length"),
- values = (_u("full"), _u("long"), _u("medium"), _u("short"))),
- value_type = Field(title=_u("ILocaleFormatLength object")))
+ title=u"Date Formats",
+ description=u"Contains various Date Formats.",
+ key_type=Choice(
+ title=u"Type",
+ description=u"Name of the format length",
+ values=(u"full", u"long", u"medium", u"short")),
+ value_type=Field(title=u"ILocaleFormatLength object"))
- defaultTimeFormat = TextLine(title=_u("Default Time Format Type"))
+ defaultTimeFormat = TextLine(title=u"Default Time Format Type")
timeFormats = Dict(
- title=_u("Time Formats"),
- description = _u("Contains various Time Formats."),
- key_type = Choice(
- title=_u("Type"),
- description = _u("Name of the format length"),
- values = (_u("full"), _u("long"), _u("medium"), _u("short"))),
- value_type = Field(title=_u("ILocaleFormatLength object")))
+ title=u"Time Formats",
+ description=u"Contains various Time Formats.",
+ key_type=Choice(
+ title=u"Type",
+ description=u"Name of the format length",
+ values=(u"full", u"long", u"medium", u"short")),
+ value_type=Field(title=u"ILocaleFormatLength object"))
- defaultDateTimeFormat = TextLine(title=_u("Default Date-Time Format Type"))
+ defaultDateTimeFormat = TextLine(title=u"Default Date-Time Format Type")
dateTimeFormats = Dict(
- title=_u("Date-Time Formats"),
- description = _u("Contains various Date-Time Formats."),
- key_type = Choice(
- title=_u("Type"),
- description = _u("Name of the format length"),
- values = (_u("full"), _u("long"), _u("medium"), _u("short"))),
- value_type = Field(title=_u("ILocaleFormatLength object")))
+ title=u"Date-Time Formats",
+ description=u"Contains various Date-Time Formats.",
+ key_type=Choice(
+ title=u"Type",
+ description=u"Name of the format length",
+ values=(u"full", u"long", u"medium", u"short")),
+ value_type=Field(title=u"ILocaleFormatLength object"))
def getMonthNames():
"""Return a list of month names."""
@@ -445,30 +446,30 @@ class ILocaleDates(Interface):
"""This object contains various data about dates, times and time zones."""
localizedPatternChars = TextLine(
- title = _u("Localized Pattern Characters"),
- description = _u("Localized pattern characters used in dates and times"))
+ title=u"Localized Pattern Characters",
+ description=u"Localized pattern characters used in dates and times")
calendars = Dict(
- title = _u("Calendar type to ILocaleCalendar"),
- key_type = Choice(
- title=_u("Calendar Type"),
- values=(_u("gregorian"),
- _u("arabic"),
- _u("chinese"),
- _u("civil-arabic"),
- _u("hebrew"),
- _u("japanese"),
- _u("thai-buddhist"))),
- value_type=Field(title=_u("Calendar"),
- description=_u("This is a ILocaleCalendar object.")))
+ title=u"Calendar type to ILocaleCalendar",
+ key_type=Choice(
+ title=u"Calendar Type",
+ values=(u"gregorian",
+ u"arabic",
+ u"chinese",
+ u"civil-arabic",
+ u"hebrew",
+ u"japanese",
+ u"thai-buddhist")),
+ value_type=Field(title=u"Calendar",
+ description=u"This is a ILocaleCalendar object."))
timezones = Dict(
- title=_u("Time zone type to ILocaleTimezone"),
- key_type=TextLine(title=_u("Time Zone type")),
- value_type=Field(title=_u("Time Zone"),
- description=_u("This is a ILocaleTimeZone object.")))
+ title=u"Time zone type to ILocaleTimezone",
+ key_type=TextLine(title=u"Time Zone type"),
+ value_type=Field(title=u"Time Zone",
+ description=u"This is a ILocaleTimeZone object."))
- def getFormatter(category, length=None, name=None, calendar=_u("gregorian")):
+ def getFormatter(category, length=None, name=None, calendar=u"gregorian"):
"""Get a date/time formatter.
`category` must be one of 'date', 'dateTime', 'time'.
@@ -482,81 +483,81 @@ class ILocaleDates(Interface):
class ILocaleCurrency(Interface):
"""Defines a particular currency."""
- type = TextLine(title=_u("Type"))
+ type = TextLine(title=u"Type")
- symbol = TextLine(title=_u("Symbol"))
+ symbol = TextLine(title=u"Symbol")
- displayName = TextLine(title=_u("Official Name"))
+ displayName = TextLine(title=u"Official Name")
- symbolChoice = Bool(title=_u("Symbol Choice"))
+ symbolChoice = Bool(title=u"Symbol Choice")
class ILocaleNumbers(Interface):
"""This object contains various data about numbers and currencies."""
symbols = Dict(
- title = _u("Number Symbols"),
- key_type = Choice(
- title = _u("Format Name"),
- values = (_u("decimal"), _u("group"), _u("list"), _u("percentSign"),
- _u("nativeZeroDigit"), _u("patternDigit"), _u("plusSign"),
- _u("minusSign"), _u("exponential"), _u("perMille"),
- _u("infinity"), _u("nan"))),
- value_type=TextLine(title=_u("Symbol")))
+ title=u"Number Symbols",
+ key_type=Choice(
+ title=u"Format Name",
+ values=(u"decimal", u"group", u"list", u"percentSign",
+ u"nativeZeroDigit", u"patternDigit", u"plusSign",
+ u"minusSign", u"exponential", u"perMille",
+ u"infinity", u"nan")),
+ value_type=TextLine(title=u"Symbol"))
- defaultDecimalFormat = TextLine(title=_u("Default Decimal Format Type"))
+ defaultDecimalFormat = TextLine(title=u"Default Decimal Format Type")
decimalFormats = Dict(
- title=_u("Decimal Formats"),
- description = _u("Contains various Decimal Formats."),
- key_type = Choice(
- title=_u("Type"),
- description = _u("Name of the format length"),
- values = (_u("full"), _u("long"), _u("medium"), _u("short"))),
- value_type = Field(title=_u("ILocaleFormatLength object")))
+ title=u"Decimal Formats",
+ description=u"Contains various Decimal Formats.",
+ key_type=Choice(
+ title=u"Type",
+ description=u"Name of the format length",
+ values=(u"full", u"long", u"medium", u"short")),
+ value_type=Field(title=u"ILocaleFormatLength object"))
- defaultScientificFormat = TextLine(title=_u("Default Scientific Format Type"))
+ defaultScientificFormat = TextLine(title=u"Default Scientific Format Type")
scientificFormats = Dict(
- title=_u("Scientific Formats"),
- description = _u("Contains various Scientific Formats."),
- key_type = Choice(
- title=_u("Type"),
- description = _u("Name of the format length"),
- values = (_u("full"), _u("long"), _u("medium"), _u("short"))),
- value_type = Field(title=_u("ILocaleFormatLength object")))
+ title=u"Scientific Formats",
+ description=u"Contains various Scientific Formats.",
+ key_type=Choice(
+ title=u"Type",
+ description=u"Name of the format length",
+ values=(u"full", u"long", u"medium", u"short")),
+ value_type=Field(title=u"ILocaleFormatLength object"))
- defaultPercentFormat = TextLine(title=_u("Default Percent Format Type"))
+ defaultPercentFormat = TextLine(title=u"Default Percent Format Type")
percentFormats = Dict(
- title=_u("Percent Formats"),
- description = _u("Contains various Percent Formats."),
- key_type = Choice(
- title=_u("Type"),
- description = _u("Name of the format length"),
- values = (_u("full"), _u("long"), _u("medium"), _u("short"))),
- value_type = Field(title=_u("ILocaleFormatLength object")))
+ title=u"Percent Formats",
+ description=u"Contains various Percent Formats.",
+ key_type=Choice(
+ title=u"Type",
+ description=u"Name of the format length",
+ values=(u"full", u"long", u"medium", u"short")),
+ value_type=Field(title=u"ILocaleFormatLength object"))
- defaultCurrencyFormat = TextLine(title=_u("Default Currency Format Type"))
+ defaultCurrencyFormat = TextLine(title=u"Default Currency Format Type")
currencyFormats = Dict(
- title=_u("Currency Formats"),
- description = _u("Contains various Currency Formats."),
- key_type = Choice(
- title=_u("Type"),
- description = _u("Name of the format length"),
- values = (_u("full"), _u("long"), _u("medium"), _u("short"))),
- value_type = Field(title=_u("ILocaleFormatLength object")))
+ title=u"Currency Formats",
+ description=u"Contains various Currency Formats.",
+ key_type=Choice(
+ title=u"Type",
+ description=u"Name of the format length",
+ values=(u"full", u"long", u"medium", u"short")),
+ value_type=Field(title=u"ILocaleFormatLength object"))
currencies = Dict(
- title=_u("Currencies"),
- description = _u("Contains various Currency data."),
- key_type = TextLine(
- title=_u("Type"),
- description = _u("Name of the format length")),
- value_type = Field(title=_u("ILocaleCurrency object")))
+ title=u"Currencies",
+ description=u"Contains various Currency data.",
+ key_type=TextLine(
+ title=u"Type",
+ description=u"Name of the format length"),
+ value_type=Field(title=u"ILocaleCurrency object"))
- def getFormatter(category, length=None, name=_u("")):
+ def getFormatter(category, length=None, name=u""):
"""Get the NumberFormat based on the category, length and name of the
format.
@@ -576,21 +577,21 @@ class ILocaleNumbers(Interface):
def getDefaultCurrency():
"""Get the default currency."""
-_orientations = [_u("left-to-right"), _u("right-to-left"),
- _u("top-to-bottom"), _u("bottom-to-top")]
+_orientations = [u"left-to-right", u"right-to-left",
+ u"top-to-bottom", u"bottom-to-top"]
class ILocaleOrientation(Interface):
"""Information about the orientation of text."""
characters = Choice(
- title = _u("Orientation of characters"),
- values = _orientations,
- default = _u("left-to-right")
+ title=u"Orientation of characters",
+ values=_orientations,
+ default=u"left-to-right"
)
lines = Choice(
- title = _u("Orientation of characters"),
- values = _orientations,
- default = _u("top-to-bottom")
+ title=u"Orientation of characters",
+ values=_orientations,
+ default=u"top-to-bottom"
)
class ILocale(Interface):
@@ -606,39 +607,39 @@ class ILocale(Interface):
"""
id = Field(
- title = _u("Locale identity"),
- description = _u("ILocaleIdentity object identifying the locale."),
- required = True,
- readonly = True)
+ title=u"Locale identity",
+ description=u"ILocaleIdentity object identifying the locale.",
+ required=True,
+ readonly=True)
displayNames = Field(
- title = _u("Display Names"),
- description = _u("""ILocaleDisplayNames object that contains localized
+ title=u"Display Names",
+ description=(u"""ILocaleDisplayNames object that contains localized
names."""))
dates = Field(
- title = _u("Dates"),
- description = _u("ILocaleDates object that contains date/time data."))
+ title=u"Dates",
+ description=u"ILocaleDates object that contains date/time data.")
numbers = Field(
- title = _u("Numbers"),
- description = _u("ILocaleNumbers object that contains number data."))
+ title=u"Numbers",
+ description=u"ILocaleNumbers object that contains number data.")
orientation = Field(
- title = _u("Orientation"),
- description = _u("ILocaleOrientation with text orientation info."))
+ title=u"Orientation",
+ description=u"ILocaleOrientation with text orientation info.")
delimiters = Dict(
- title=_u("Delimiters"),
- description = _u("Contains various Currency data."),
- key_type = Choice(
- title=_u("Delimiter Type"),
- description = _u("Delimiter name."),
- values=(_u("quotationStart"),
- _u("quotationEnd"),
- _u("alternateQuotationStart"),
- _u("alternateQuotationEnd"))),
- value_type = Field(title=_u("Delimiter symbol")))
+ title=u"Delimiters",
+ description=u"Contains various Currency data.",
+ key_type=Choice(
+ title=u"Delimiter Type",
+ description=u"Delimiter name.",
+ values=(u"quotationStart",
+ u"quotationEnd",
+ u"alternateQuotationStart",
+ u"alternateQuotationEnd")),
+ value_type=Field(title=u"Delimiter symbol"))
def getLocaleID():
"""Return a locale id as specified in the LDML specification"""
@@ -655,8 +656,8 @@ class ILocaleInheritance(Interface):
__parent__ = Attribute("The parent in the location hierarchy")
__name__ = TextLine(
- title = _u("The name within the parent"),
- description=_u("""The parent can be traversed with this name to get
+ title=u"The name within the parent",
+ description=(u"""The parent can be traversed with this name to get
the object."""))
def getInheritedSelf():
diff --git a/src/zope/i18n/locales/__init__.py b/src/zope/i18n/locales/__init__.py
index f36edd9..fe876d5 100644
--- a/src/zope/i18n/locales/__init__.py
+++ b/src/zope/i18n/locales/__init__.py
@@ -16,8 +16,7 @@
__docformat__ = 'restructuredtext'
import os
-from datetime import datetime, date
-from time import strptime
+from datetime import date
from zope.interface import implementer
from zope.i18n.interfaces.locales import ILocale
@@ -32,7 +31,7 @@ from zope.i18n.format import NumberFormat, DateTimeFormat
from zope.i18n.locales.inheritance import \
AttributeInheritance, InheritingDictionary, NoParentException
from zope.i18n.locales.provider import LocaleProvider, LoadLocaleError
-from .._compat import _u
+
# Setup the locale directory
from zope import i18n
@@ -125,6 +124,7 @@ class LocaleVersion(object):
Examples::
+ >>> from datetime import datetime
>>> (LocaleVersion('1.0', datetime(2004, 1, 1), 'no notes') ==
... LocaleVersion('1.0', datetime(2004, 1, 1), 'no notes again'))
True
@@ -146,7 +146,7 @@ class LocaleVersion(object):
def __init__(self, number, generationDate, notes):
"""Initialize object."""
self.number = number
- assert(isinstance(generationDate, (date, type(None))))
+ assert isinstance(generationDate, (date, type(None)))
self.generationDate = generationDate
self.notes = notes
@@ -224,8 +224,8 @@ class LocaleFormat(object):
def __init__(self, type=None):
"""Initialize the object."""
self.type = type
- self.displayName = _u("")
- self.pattern = _u("")
+ self.displayName = u""
+ self.pattern = u""
@implementer(ILocaleFormatLength)
@@ -246,7 +246,7 @@ class LocaleMonthContext(AttributeInheritance):
def __init__(self, type=None):
"""Initialize the object."""
self.type = type
- self.default = _u("wide")
+ self.default = u"wide"
@implementer(ILocaleDayContext)
@@ -255,7 +255,7 @@ class LocaleDayContext(AttributeInheritance):
def __init__(self, type=None):
"""Initialize the object."""
self.type = type
- self.default = _u("wide")
+ self.default = u"wide"
@implementer(ILocaleCalendar)
@@ -280,44 +280,44 @@ class LocaleCalendar(AttributeInheritance):
>>> locale.calendar = LocaleCalendar('gregorian')
>>> root.calendar.months = InheritingDictionary(
- ... {1: (_u("January"), _u("Jan")), 2: (_u("February"), _u("Feb"))})
+ ... {1: (u"January", u"Jan"), 2: (u"February", u"Feb")})
>>> locale.calendar.months = InheritingDictionary(
- ... {2: (_u("Februar"), _u("Feb")), 3: (_u("Maerz"), _u("Mrz"))})
+ ... {2: (u"Februar", u"Feb"), 3: (u"Maerz", u"Mrz")})
>>> locale.calendar.getMonthNames()[:4]
[u'January', u'Februar', u'Maerz', None]
- >>> locale.calendar.getMonthTypeFromName(_u("January"))
+ >>> locale.calendar.getMonthTypeFromName(u"January")
1
- >>> locale.calendar.getMonthTypeFromName(_u("Februar"))
+ >>> locale.calendar.getMonthTypeFromName(u"Februar")
2
>>> locale.calendar.getMonthAbbreviations()[:4]
[u'Jan', u'Feb', u'Mrz', None]
- >>> locale.calendar.getMonthTypeFromAbbreviation(_u("Jan"))
+ >>> locale.calendar.getMonthTypeFromAbbreviation(u"Jan")
1
- >>> locale.calendar.getMonthTypeFromAbbreviation(_u("Mrz"))
+ >>> locale.calendar.getMonthTypeFromAbbreviation(u"Mrz")
3
>>> root.calendar.days = InheritingDictionary(
- ... {1: (_u("Monday"), _u("Mon")), 2: (_u("Tuesday"), _u("Tue"))})
+ ... {1: (u"Monday", u"Mon"), 2: (u"Tuesday", u"Tue")})
>>> locale.calendar.days = InheritingDictionary(
- ... {2: (_u("Dienstag"), _u("Die")), 3: (_u("Mittwoch"), _u("Mit"))})
+ ... {2: (u"Dienstag", u"Die"), 3: (u"Mittwoch", u"Mit")})
>>> locale.calendar.getDayNames()[:4]
[u'Monday', u'Dienstag', u'Mittwoch', None]
- >>> locale.calendar.getDayTypeFromName(_u("Monday"))
+ >>> locale.calendar.getDayTypeFromName(u"Monday")
1
- >>> locale.calendar.getDayTypeFromName(_u("Dienstag"))
+ >>> locale.calendar.getDayTypeFromName(u"Dienstag")
2
>>> locale.calendar.getDayAbbreviations()[:4]
[u'Mon', u'Die', u'Mit', None]
- >>> locale.calendar.getDayTypeFromAbbreviation(_u("Mon"))
+ >>> locale.calendar.getDayTypeFromAbbreviation(u"Mon")
1
- >>> locale.calendar.getDayTypeFromAbbreviation(_u("Die"))
+ >>> locale.calendar.getDayTypeFromAbbreviation(u"Die")
2
Let's test the direct attribute access as well.
- >>> root.am = _u("AM")
- >>> root.pm = _u("PM")
- >>> locale.pm = _u("nachm.")
+ >>> root.am = u"AM"
+ >>> root.pm = u"PM"
+ >>> locale.pm = u"nachm."
>>> locale.pm
u'nachm.'
>>> locale.am
@@ -370,8 +370,6 @@ class LocaleCalendar(AttributeInheritance):
def isWeekend(self, datetime):
"""See zope.i18n.interfaces.ILocaleCalendar"""
- day = datetime.weekday()
- time = datetime.time()
# TODO: Implement this method
return False
@@ -404,12 +402,12 @@ class LocaleDates(AttributeInheritance):
>>> fulllength = LocaleFormatLength()
>>> format = LocaleFormat()
- >>> format.pattern = _u("EEEE, d. MMMM yyyy")
+ >>> format.pattern = u"EEEE, d. MMMM yyyy"
>>> fulllength.formats = {None: format}
>>> mediumlength = LocaleFormatLength()
>>> format = LocaleFormat()
- >>> format.pattern = _u("dd.MM.yyyy")
+ >>> format.pattern = u"dd.MM.yyyy"
>>> mediumlength.formats = {None: format}
>>> cal.dateFormats = {'full': fulllength, 'medium': mediumlength}
@@ -427,12 +425,12 @@ class LocaleDates(AttributeInheritance):
>>> fulllength = LocaleFormatLength()
>>> format = LocaleFormat()
- >>> format.pattern = _u("H:mm' Uhr 'z")
+ >>> format.pattern = u"H:mm' Uhr 'z"
>>> fulllength.formats = {None: format}
>>> mediumlength = LocaleFormatLength()
>>> format = LocaleFormat()
- >>> format.pattern = _u("HH:mm:ss")
+ >>> format.pattern = u"HH:mm:ss"
>>> mediumlength.formats = {None: format}
>>> cal.timeFormats = {'full': fulllength, 'medium': mediumlength}
@@ -451,7 +449,7 @@ class LocaleDates(AttributeInheritance):
>>> length = LocaleFormatLength()
>>> format = LocaleFormat()
- >>> format.pattern = _u("{1} {0}")
+ >>> format.pattern = u"{1} {0}"
>>> length.formats = {None: format}
>>> cal.dateTimeFormats = {None: length}
@@ -480,15 +478,15 @@ class LocaleDates(AttributeInheritance):
"""
def getFormatter(self, category, length=None, name=None,
- calendar=_u("gregorian")):
+ calendar=u"gregorian"):
"""See zope.i18n.interfaces.locales.ILocaleDates"""
- if category not in (_u("date"), _u("time"), _u("dateTime")):
+ if category not in (u"date", u"time", u"dateTime"):
raise ValueError('Invalid category: %s' % category)
- if calendar not in (_u("gregorian"), _u("arabic"), _u("chinese"),
- _u("civil-arabic"), _u("hebrew"), _u("japanese"),
- _u("thai-buddhist")):
+ if calendar not in (u"gregorian", u"arabic", u"chinese",
+ u"civil-arabic", u"hebrew", u"japanese",
+ u"thai-buddhist"):
raise ValueError('Invalid calendar: %s' % calendar)
- if length not in (_u("short"), _u("medium"), _u("long"), _u("full"), None):
+ if length not in (u"short", u"medium", u"long", u"full", None):
raise ValueError('Invalid format length: %s' % length)
cal = self.calendars[calendar]
@@ -556,7 +554,7 @@ class LocaleNumbers(AttributeInheritance):
>>> length = LocaleFormatLength()
>>> format = LocaleFormat()
- >>> format.pattern = _u("#,##0.###;-#,##0.###")
+ >>> format.pattern = u"#,##0.###;-#,##0.###"
>>> length.formats = {None: format}
>>> numbers.decimalFormats = {None: length}
>>> formatter = numbers.getFormatter('decimal')
@@ -571,11 +569,11 @@ class LocaleNumbers(AttributeInheritance):
>>> longlength = LocaleFormatLength('long')
>>> format = LocaleFormat()
- >>> format.pattern = _u("0.000###E+00")
+ >>> format.pattern = u"0.000###E+00"
>>> longlength.formats = {None: format}
>>> mediumlength = LocaleFormatLength('long')
>>> format = LocaleFormat()
- >>> format.pattern = _u("0.00##E+00")
+ >>> format.pattern = u"0.00##E+00"
>>> mediumlength.formats = {None: format}
>>> numbers.scientificFormats = {'long': longlength,
... 'medium': mediumlength}
@@ -592,9 +590,9 @@ class LocaleNumbers(AttributeInheritance):
>>> longlength = LocaleFormatLength('long')
>>> fooformat = LocaleFormat()
- >>> fooformat.pattern = _u("0.##0%")
+ >>> fooformat.pattern = u"0.##0%"
>>> barformat = LocaleFormat()
- >>> barformat.pattern = _u("0%")
+ >>> barformat.pattern = u"0%"
>>> longlength.formats = {None: fooformat, 'bar': barformat}
>>> numbers.percentFormats = {'long': longlength}
>>> numbers.defaultPercentFormat = 'long'
@@ -616,8 +614,8 @@ class LocaleNumbers(AttributeInheritance):
def getFormatter(self, category, length=None, name=None):
"""See zope.i18n.interfaces.locales.ILocaleNumbers"""
- assert category in (_u("decimal"), _u("percent"), _u("scientific"), _u("currency"))
- assert length in (_u("short"), _u("medium"), _u("long"), _u("full"), None)
+ assert category in (u"decimal", u"percent", u"scientific", u"currency")
+ assert length in (u"short", u"medium", u"long", u"full", None)
formats = getattr(self, category+'Formats')
if length is None:
diff --git a/src/zope/i18n/locales/fallbackcollator.txt b/src/zope/i18n/locales/fallbackcollator.txt
index 727d6b1..367e4e6 100644
--- a/src/zope/i18n/locales/fallbackcollator.txt
+++ b/src/zope/i18n/locales/fallbackcollator.txt
@@ -31,8 +31,7 @@ application code should certainly *not* count on this.
Now, we can pass the collator's key method to sort functions to sort
strings in a slightly friendly way:
- >>> from zope.i18n._compat import _u
- >>> sorted([_u("Sam"), _u("sally"), _u("Abe"), _u("alice"), _u("Terry"), _u("tim")],
+ >>> sorted([u"Sam", u"sally", u"Abe", u"alice", u"Terry", u"tim"],
... key=collator.key)
[u'Abe', u'alice', u'sally', u'Sam', u'Terry', u'tim']
@@ -42,23 +41,23 @@ then returns a tuple with the result of lower-casing the normalized
string and the normalized string. We can see this by calling the key
method, which converts unicode strings to collation keys:
- >>> collator.key(_u("Sam"))
+ >>> collator.key(u"Sam")
(u'sam', u'Sam')
- >>> collator.key(_u("\xc6\xf8a\u030a"))
+ >>> collator.key(u"\xc6\xf8a\u030a")
(u'\xe6\xf8\xe5', u'\xc6\xf8\xe5')
There is also a cmp function for comparing strings:
- >>> collator.cmp(_u("Terry"), _u("sally"))
+ >>> collator.cmp(u"Terry", u"sally")
1
- >>> collator.cmp(_u("sally"), _u("Terry"))
+ >>> collator.cmp(u"sally", u"Terry")
-1
- >>> collator.cmp(_u("terry"), _u("Terry"))
+ >>> collator.cmp(u"terry", u"Terry")
1
- >>> collator.cmp(_u("terry"), _u("terry"))
+ >>> collator.cmp(u"terry", u"terry")
0
diff --git a/src/zope/i18n/locales/tests/test_xmlfactory.py b/src/zope/i18n/locales/tests/test_xmlfactory.py
index f0857c8..792c96d 100644
--- a/src/zope/i18n/locales/tests/test_xmlfactory.py
+++ b/src/zope/i18n/locales/tests/test_xmlfactory.py
@@ -14,29 +14,25 @@
"""Testing all XML Locale functionality.
"""
import os
-from unittest import TestCase, TestSuite, makeSuite, main
+from unittest import TestCase, TestSuite
from zope.i18n.locales.xmlfactory import LocaleFactory
-from zope.i18n.format import parseDateTimePattern, parseNumberPattern
import zope.i18n
class LocaleXMLFileTestCase(TestCase):
"""This test verifies that every locale XML file can be loaded."""
- # only run when running tests of level 2
- level = 2
-
def __init__(self, path):
self.__path = path
TestCase.__init__(self)
-
+
def runTest(self):
# Loading Locale object
- locale = LocaleFactory(self.__path)()
+ LocaleFactory(self.__path)()
# XXX: The tests below are commented out because it's not
# necessary for the xml files to have all format definitions.
-
+
## Making sure all number format patterns parse
#for category in (u'decimal', u'scientific', u'percent', u'currency'):
# for length in getattr(locale.numbers, category+'Formats').values():
@@ -50,20 +46,17 @@ class LocaleXMLFileTestCase(TestCase):
# for format in length.formats.values():
# self.assert_(
# parseDateTimePattern(format.pattern) is not None)
-
-
-def test_suite():
- suite = TestSuite()
- locale_dir = os.path.join(os.path.dirname(zope.i18n.__file__),
- 'locales', 'data')
- for path in os.listdir(locale_dir):
- if not path.endswith(".xml"):
- continue
- path = os.path.join(locale_dir, path)
- case = LocaleXMLFileTestCase(path)
- suite.addTest(case)
- return suite
-if __name__ == '__main__':
- main(defaultTest='test_suite')
+
+def test_suite():
+ suite = TestSuite()
+ locale_dir = os.path.join(os.path.dirname(zope.i18n.__file__),
+ 'locales', 'data')
+ for path in os.listdir(locale_dir):
+ if not path.endswith(".xml"):
+ continue
+ path = os.path.join(locale_dir, path)
+ case = LocaleXMLFileTestCase(path)
+ suite.addTest(case)
+ return suite
diff --git a/src/zope/i18n/locales/xmlfactory.py b/src/zope/i18n/locales/xmlfactory.py
index 5d4fb3b..98525dc 100644
--- a/src/zope/i18n/locales/xmlfactory.py
+++ b/src/zope/i18n/locales/xmlfactory.py
@@ -22,9 +22,9 @@ from zope.i18n.locales import LocaleFormat, LocaleFormatLength, dayMapping
from zope.i18n.locales import LocaleOrientation, LocaleDayContext
from zope.i18n.locales import LocaleMonthContext, calendarAliases
from zope.i18n.locales.inheritance import InheritingDictionary
-from .._compat import _u
-_BLANK = _u('')
+
+_BLANK = u''
class LocaleFactory(object):
"""This class creates a Locale object from an ICU XML file."""
@@ -52,7 +52,7 @@ class LocaleFactory(object):
>>> factory = LocaleFactory(None)
>>> from xml.dom.minidom import parseString
- >>> xml = _u('''
+ >>> xml = (u'''
... <identity>
... <version number="1.0">Some notes</version>
... <generation date="2003-12-19" />
@@ -91,7 +91,7 @@ class LocaleFactory(object):
Example::
>>> from xml.dom.minidom import parseString
- >>> xml = _u('''
+ >>> xml = (u'''
... <ldml>
... <identity>
... <version number="1.0"/>
@@ -142,7 +142,7 @@ class LocaleFactory(object):
>>> factory = LocaleFactory(None)
>>> from xml.dom.minidom import parseString
- >>> xml = _u('''
+ >>> xml = (u'''
... <displayNames>
... <types>
... <type type="Fallback" key="calendar"></type>
@@ -164,9 +164,9 @@ class LocaleFactory(object):
[(u'chinese', u'calendar'), (u'gregorian', u'calendar')]
>>> keys[4:]
[(u'stroke', u'collation'), (u'traditional', u'collation')]
- >>> types[(_u('chinese'), _u('calendar'))]
+ >>> types[(u'chinese', u'calendar')]
u'CHINESE'
- >>> types[(_u('stroke'), _u('collation'))]
+ >>> types[(u'stroke', u'collation')]
u'STROKE'
"""
# 'types' node has not to exist
@@ -188,7 +188,7 @@ class LocaleFactory(object):
Example::
>>> from xml.dom.minidom import parseString
- >>> xml = _u('''
+ >>> xml = (u'''
... <ldml>
... <localeDisplayNames>
... <languages>
@@ -227,38 +227,38 @@ class LocaleFactory(object):
>>> keys.sort()
>>> keys
[u'Fallback', u'aa', u'ab']
- >>> names.languages[_u("aa")]
+ >>> names.languages[u"aa"]
u'aa'
>>> keys = names.scripts.keys()
>>> keys.sort()
>>> keys
[u'Arab', u'Armn']
- >>> names.scripts[_u("Arab")]
+ >>> names.scripts[u"Arab"]
u'Arab'
>>> keys = names.territories.keys()
>>> keys.sort()
>>> keys
[u'AD', u'AE']
- >>> names.territories[_u("AD")]
+ >>> names.territories[u"AD"]
u'AD'
>>> keys = names.variants.keys()
>>> keys.sort()
>>> keys
[u'Fallback', u'POSIX']
- >>> names.variants[_u("Fallback")]
+ >>> names.variants[u"Fallback"]
u''
>>> keys = names.keys.keys()
>>> keys.sort()
>>> keys
[u'calendar', u'collation']
- >>> names.keys[_u("calendar")]
+ >>> names.keys[u"calendar"]
u'CALENDAR'
- >>> names.types[(_u("stroke"), _u("collation"))]
+ >>> names.types[(u"stroke", u"collation")]
u'STROKE'
"""
displayNames = LocaleDisplayNames()
@@ -298,7 +298,7 @@ class LocaleFactory(object):
>>> calendar = CalendarStub()
>>> factory = LocaleFactory(None)
>>> from xml.dom.minidom import parseString
- >>> xml = _u('''
+ >>> xml = (u'''
... <months>
... <default type="format" />
... <monthContext type="format">
@@ -342,17 +342,17 @@ class LocaleFactory(object):
>>> calendar.defaultMonthContext
u'format'
- >>> ctx = calendar.monthContexts[_u("format")]
+ >>> ctx = calendar.monthContexts[u"format"]
>>> ctx.defaultWidth
u'wide'
- >>> names = [ctx.months[_u("wide")][type] for type in range(1,13)]
+ >>> names = [ctx.months[u"wide"][type] for type in range(1,13)]
>>> names[:7]
[u'Januar', u'Februar', u'Maerz', u'April', u'Mai', u'Juni', u'Juli']
>>> names[7:]
[u'August', u'September', u'Oktober', u'November', u'Dezember']
- >>> abbrs = [ctx.months[_u("abbreviated")][type] for type in range(1,13)]
+ >>> abbrs = [ctx.months[u"abbreviated"][type] for type in range(1,13)]
>>> abbrs[:6]
[u'Jan', u'Feb', u'Mrz', u'Apr', u'Mai', u'Jun']
>>> abbrs[6:]
@@ -447,7 +447,7 @@ class LocaleFactory(object):
>>> calendar = CalendarStub()
>>> factory = LocaleFactory(None)
>>> from xml.dom.minidom import parseString
- >>> xml = _u('''
+ >>> xml = (u'''
... <days>
... <default type="format" />
... <dayContext type="format">
@@ -481,17 +481,17 @@ class LocaleFactory(object):
>>> calendar.defaultDayContext
u'format'
- >>> ctx = calendar.dayContexts[_u("format")]
+ >>> ctx = calendar.dayContexts[u"format"]
>>> ctx.defaultWidth
u'wide'
- >>> names = [ctx.days[_u("wide")][type] for type in range(1,8)]
+ >>> names = [ctx.days[u"wide"][type] for type in range(1,8)]
>>> names[:4]
[u'Montag', u'Dienstag', u'Mittwoch', u'Donnerstag']
>>> names[4:]
[u'Freitag', u'Samstag', u'Sonntag']
- >>> abbrs = [ctx.days[_u("abbreviated")][type] for type in range(1,8)]
+ >>> abbrs = [ctx.days[u"abbreviated"][type] for type in range(1,8)]
>>> abbrs
[u'Mo', u'Di', u'Mi', u'Do', u'Fr', u'Sa', u'So']
@@ -580,7 +580,7 @@ class LocaleFactory(object):
>>> calendar = CalendarStub()
>>> factory = LocaleFactory(None)
>>> from xml.dom.minidom import parseString
- >>> xml = _u('''
+ >>> xml = (u'''
... <calendar type="gregorian">
... <week>
... <minDays count="1"/>
@@ -640,7 +640,7 @@ class LocaleFactory(object):
>>> calendar = CalendarStub()
>>> factory = LocaleFactory(None)
>>> from xml.dom.minidom import parseString
- >>> xml = _u('''
+ >>> xml = (u'''
... <calendar type="gregorian">
... <eras>
... <eraAbbr>
@@ -698,7 +698,7 @@ class LocaleFactory(object):
>>> factory = LocaleFactory(None)
>>> from xml.dom.minidom import parseString
- >>> xml = _u('''
+ >>> xml = (u'''
... <dateFormats>
... <default type="medium"/>
... <dateFormatLength type="full">
@@ -723,13 +723,13 @@ class LocaleFactory(object):
... dom.documentElement, 'dateFormatLength', 'dateFormat')
>>> default
u'medium'
- >>> lengths[_u("full")].formats[None].pattern
+ >>> lengths[u"full"].formats[None].pattern
u'EEEE, MMMM d, yyyy'
- >>> lengths[_u("medium")].default
+ >>> lengths[u"medium"].default
u'DateFormatsKey2'
- >>> lengths[_u("medium")].formats['DateFormatsKey3'].pattern
+ >>> lengths[u"medium"].formats['DateFormatsKey3'].pattern
u'MMM dd, yyyy'
- >>> lengths[_u("medium")].formats['DateFormatsKey2'].displayName
+ >>> lengths[u"medium"].formats['DateFormatsKey2'].displayName
u'Standard Date'
"""
formats_default = None
@@ -771,7 +771,7 @@ class LocaleFactory(object):
>>> factory = LocaleFactory(None)
>>> from xml.dom.minidom import parseString
- >>> xml = _u('''
+ >>> xml = (u'''
... <dates>
... <calendars>
... <calendar type="gregorian">
@@ -883,9 +883,9 @@ class LocaleFactory(object):
self._extractEras(cal_node, calendar)
for formatsName, lengthName, formatName in (
- ('dateFormats', 'dateFormatLength', 'dateFormat'),
- ('timeFormats', 'timeFormatLength', 'timeFormat'),
- ('dateTimeFormats', 'dateTimeFormatLength', 'dateTimeFormat')):
+ ('dateFormats', 'dateFormatLength', 'dateFormat'),
+ ('timeFormats', 'timeFormatLength', 'timeFormat'),
+ ('dateTimeFormats', 'dateTimeFormatLength', 'dateTimeFormat')):
formats_nodes = cal_node.getElementsByTagName(formatsName)
if formats_nodes:
@@ -912,7 +912,7 @@ class LocaleFactory(object):
>>> factory = LocaleFactory(None)
>>> from xml.dom.minidom import parseString
- >>> xml = _u('''
+ >>> xml = (u'''
... <dates>
... <timeZoneNames>
... <zone type="America/Los_Angeles" >
@@ -945,11 +945,11 @@ class LocaleFactory(object):
>>> keys.sort()
>>> keys
[u'America/Los_Angeles', u'Europe/London']
- >>> zones[_u("Europe/London")].names[_u("generic")]
+ >>> zones[u"Europe/London"].names[u"generic"]
(u'British Time', None)
- >>> zones[_u("Europe/London")].cities
+ >>> zones[u"Europe/London"].cities
[u'York']
- >>> zones[_u("America/Los_Angeles")].names[_u("generic")]
+ >>> zones[u"America/Los_Angeles"].names[u"generic"]
(u'Pacific Time', u'PT')
"""
tz_names = dates_node.getElementsByTagName('timeZoneNames')
@@ -964,7 +964,7 @@ class LocaleFactory(object):
# get the short and long name node
long = node.getElementsByTagName('long')
short = node.getElementsByTagName('short')
- for type in (_u("generic"), _u("standard"), _u("daylight")):
+ for type in (u"generic", u"standard", u"daylight"):
# get long name
long_desc = None
if long:
@@ -1012,7 +1012,7 @@ class LocaleFactory(object):
>>> factory = LocaleFactory(None)
>>> from xml.dom.minidom import parseString
- >>> xml = _u('''
+ >>> xml = (u'''
... <numbers>
... <symbols>
... <decimal>.</decimal>
@@ -1049,10 +1049,10 @@ class LocaleFactory(object):
return
symbols = InheritingDictionary()
- for name in (_u("decimal"), _u("group"), _u("list"), _u("percentSign"),
- _u("nativeZeroDigit"), _u("patternDigit"), _u("plusSign"),
- _u("minusSign"), _u("exponential"), _u("perMille"),
- _u("infinity"), _u("nan")):
+ for name in (u"decimal", u"group", u"list", u"percentSign",
+ u"nativeZeroDigit", u"patternDigit", u"plusSign",
+ u"minusSign", u"exponential", u"perMille",
+ u"infinity", u"nan"):
nodes = symbols_nodes[0].getElementsByTagName(name)
if nodes:
symbols[name] = self._getText(nodes[0].childNodes)
@@ -1078,7 +1078,7 @@ class LocaleFactory(object):
>>> numbers = Numbers()
>>> factory = LocaleFactory(None)
>>> from xml.dom.minidom import parseString
- >>> xml = _u('''
+ >>> xml = (u'''
... <numbers>
... <decimalFormats>
... <decimalFormatLength type="long">
@@ -1118,24 +1118,24 @@ class LocaleFactory(object):
>>> dom = parseString(xml)
>>> factory._extractNumberFormats(dom.documentElement, numbers)
- >>> numbers.decimalFormats[_u("long")].formats[None].pattern
+ >>> numbers.decimalFormats[u"long"].formats[None].pattern
u'#,##0.###'
>>> numbers.defaultScientificFormat
u'long'
- >>> numbers.scientificFormats[_u("long")].formats[None].pattern
+ >>> numbers.scientificFormats[u"long"].formats[None].pattern
u'0.000###E+00'
- >>> numbers.scientificFormats[_u("medium")].formats[None].pattern
+ >>> numbers.scientificFormats[u"medium"].formats[None].pattern
u'0.00##E+00'
- >>> numbers.percentFormats[_u("long")].formats[None].pattern
+ >>> numbers.percentFormats[u"long"].formats[None].pattern
u'#,##0%'
- >>> numbers.percentFormats.get(_u("medium"), None) is None
+ >>> numbers.percentFormats.get(u"medium", None) is None
True
- >>> numbers.currencyFormats[_u("long")].formats[None].pattern
+ >>> numbers.currencyFormats[u"long"].formats[None].pattern
u'$ #,##0.00;($ #,##0.00)'
- >>> numbers.currencyFormats.get(_u("medium"), None) is None
+ >>> numbers.currencyFormats.get(u"medium", None) is None
True
"""
@@ -1161,7 +1161,7 @@ class LocaleFactory(object):
>>> factory = LocaleFactory(None)
>>> from xml.dom.minidom import parseString
- >>> xml = _u('''
+ >>> xml = (u'''
... <numbers>
... <currencies>
... <currency type="USD">
@@ -1210,7 +1210,7 @@ class LocaleFactory(object):
if nodes:
currency.symbol = self._getText(nodes[0].childNodes)
currency.symbolChoice = \
- nodes[0].getAttribute('choice') == _u("true")
+ nodes[0].getAttribute('choice') == u"true"
nodes = curr_node.getElementsByTagName('displayName')
if nodes:
@@ -1245,7 +1245,7 @@ class LocaleFactory(object):
>>> factory = LocaleFactory(None)
>>> from xml.dom.minidom import parseString
- >>> xml = _u('''
+ >>> xml = (u'''
... <ldml>
... <delimiters>
... <quotationStart>``</quotationStart>
@@ -1258,13 +1258,13 @@ class LocaleFactory(object):
>>> factory._data = parseString(xml).documentElement
>>> delimiters = factory._extractDelimiters()
- >>> delimiters[_u("quotationStart")]
+ >>> delimiters[u"quotationStart"]
u'``'
- >>> delimiters[_u("quotationEnd")]
+ >>> delimiters[u"quotationEnd"]
u"''"
- >>> delimiters[_u("alternateQuotationStart")]
+ >>> delimiters[u"alternateQuotationStart"]
u'`'
- >>> delimiters[_u("alternateQuotationEnd")]
+ >>> delimiters[u"alternateQuotationEnd"]
u"'"
Escape: "'"
@@ -1275,8 +1275,8 @@ class LocaleFactory(object):
return
delimiters = InheritingDictionary()
- for name in (_u('quotationStart'), _u("quotationEnd"),
- _u("alternateQuotationStart"), _u("alternateQuotationEnd")):
+ for name in (u'quotationStart', u"quotationEnd",
+ u"alternateQuotationStart", u"alternateQuotationEnd"):
nodes = delimiters_nodes[0].getElementsByTagName(name)
if nodes:
delimiters[name] = self._getText(nodes[0].childNodes)
@@ -1289,7 +1289,7 @@ class LocaleFactory(object):
>>> factory = LocaleFactory(None)
>>> from xml.dom.minidom import parseString
- >>> xml = _u('''
+ >>> xml = (u'''
... <ldml>
... <layout>
... <orientation lines="bottom-to-top" characters="right-to-left" />
@@ -1307,7 +1307,7 @@ class LocaleFactory(object):
if not orientation_nodes:
return
orientation = LocaleOrientation()
- for name in (_u("characters"), _u("lines")):
+ for name in (u"characters", u"lines"):
value = orientation_nodes[0].getAttribute(name)
if value:
setattr(orientation, name, value)
diff --git a/src/zope/i18n/simpletranslationdomain.py b/src/zope/i18n/simpletranslationdomain.py
index 1fb16f5..6d8ef10 100644
--- a/src/zope/i18n/simpletranslationdomain.py
+++ b/src/zope/i18n/simpletranslationdomain.py
@@ -13,16 +13,12 @@
##############################################################################
"""This is a simple implementation of the ITranslationDomain interface.
"""
-import sys
-
from zope.interface import implementer
from zope.component import getUtility
from zope.i18n.interfaces import ITranslationDomain, INegotiator
from zope.i18n import interpolate
-PY3 = sys.version_info[0] == 3
-if PY3:
- unicode = str
+text_type = str if bytes is not str else unicode
@implementer(ITranslationDomain)
class SimpleTranslationDomain(object):
@@ -64,7 +60,7 @@ class SimpleTranslationDomain(object):
# Find a translation; if nothing is found, use the default
# value
if default is None:
- default = unicode(msgid)
+ default = text_type(msgid)
text = self.messages.get((target_language, msgid))
if text is None:
text = default
diff --git a/src/zope/i18n/testmessagecatalog.py b/src/zope/i18n/testmessagecatalog.py
index 4bebda2..804c6a8 100644
--- a/src/zope/i18n/testmessagecatalog.py
+++ b/src/zope/i18n/testmessagecatalog.py
@@ -17,7 +17,6 @@
from zope import interface
import zope.i18n.interfaces
from zope.i18n.translationdomain import TranslationDomain
-from ._compat import _u
@interface.implementer(zope.i18n.interfaces.IGlobalMessageCatalog)
class TestMessageCatalog:
@@ -30,11 +29,11 @@ class TestMessageCatalog:
def queryMessage(self, msgid, default=None):
default = getattr(msgid, 'default', default)
if default != None and default != msgid:
- msg = _u("%s (%s)") % (msgid, default)
+ msg = u"%s (%s)" % (msgid, default)
else:
msg = msgid
- return _u("[[%s][%s]]") % (self.domain, msg)
+ return u"[[%s][%s]]" % (self.domain, msg)
getMessage = queryMessage
@@ -45,7 +44,7 @@ class TestMessageCatalog:
pass
@interface.implementer(zope.i18n.interfaces.ITranslationDomain)
-def TestMessageFallbackDomain(domain_id=_u("")):
+def TestMessageFallbackDomain(domain_id=u""):
domain = TranslationDomain(domain_id)
domain.addCatalog(TestMessageCatalog(domain_id))
return domain
diff --git a/src/zope/i18n/tests/locale3/en/LC_MESSAGES/zope-i18n.mo b/src/zope/i18n/tests/locale3/en/LC_MESSAGES/zope-i18n.mo
index 56ec799..8bdb36f 100644
--- a/src/zope/i18n/tests/locale3/en/LC_MESSAGES/zope-i18n.mo
+++ b/src/zope/i18n/tests/locale3/en/LC_MESSAGES/zope-i18n.mo
Binary files differ
diff --git a/src/zope/i18n/tests/test_formats.py b/src/zope/i18n/tests/test_formats.py
index ce235c3..8ada776 100644
--- a/src/zope/i18n/tests/test_formats.py
+++ b/src/zope/i18n/tests/test_formats.py
@@ -14,11 +14,11 @@
"""This module tests the Formats and everything that goes with it.
"""
import decimal
-import os
import datetime
-import pytz
import pickle
-from unittest import TestCase, TestSuite, makeSuite
+from unittest import TestCase, TestSuite
+
+import pytz
from zope.i18n.interfaces import IDateTimeFormat
from zope.i18n.format import DateTimeFormat
@@ -29,21 +29,21 @@ from zope.i18n.interfaces import INumberFormat
from zope.i18n.format import NumberFormat, NumberParseError
from zope.i18n.format import parseNumberPattern
-from .._compat import _u
class LocaleStub(object):
pass
class LocaleCalendarStub(object):
- type = _u("gregorian")
+ type = u"gregorian"
- months = { 1: ('Januar', 'Jan'), 2: ('Februar', 'Feb'),
- 3: ('Maerz', 'Mrz'), 4: ('April', 'Apr'),
- 5: ('Mai', 'Mai'), 6: ('Juni', 'Jun'),
- 7: ('Juli', 'Jul'), 8: ('August', 'Aug'),
- 9: ('September', 'Sep'), 10: ('Oktober', 'Okt'),
- 11: ('November', 'Nov'), 12: ('Dezember', 'Dez')}
+ months = {
+ 1: ('Januar', 'Jan'), 2: ('Februar', 'Feb'),
+ 3: ('Maerz', 'Mrz'), 4: ('April', 'Apr'),
+ 5: ('Mai', 'Mai'), 6: ('Juni', 'Jun'),
+ 7: ('Juli', 'Jul'), 8: ('August', 'Aug'),
+ 9: ('September', 'Sep'), 10: ('Oktober', 'Okt'),
+ 11: ('November', 'Nov'), 12: ('Dezember', 'Dez')}
days = {1: ('Montag', 'Mo'), 2: ('Dienstag', 'Di'),
3: ('Mittwoch', 'Mi'), 4: ('Donnerstag', 'Do'),
@@ -224,9 +224,9 @@ class TestBuildDateTimeParseInfo(TestCase):
self.assertEqual(self.info(('M', 2)), '([0-9]{2})')
def testMonthNames(self):
- names = [_u("Januar"), _u("Februar"), _u("Maerz"), _u("April"),
- _u("Mai"), _u("Juni"), _u("Juli"), _u("August"), _u("September"), _u("Oktober"),
- _u("November"), _u("Dezember")]
+ names = [u"Januar", u"Februar", u"Maerz", u"April",
+ u"Mai", u"Juni", u"Juli", u"August", u"September", u"Oktober",
+ u"November", u"Dezember"]
self.assertEqual(self.info(('M', 4)), '('+'|'.join(names)+')')
def testMonthAbbr(self):
@@ -550,54 +550,54 @@ class TestDateTimeFormat(TestCase):
def testFormatDayInYear(self):
self.assertEqual(
self.format.format(datetime.date(2003, 1, 3), 'D'),
- _u("3"))
+ u"3")
self.assertEqual(
self.format.format(datetime.date(2003, 1, 3), 'DD'),
- _u("03"))
+ u"03")
self.assertEqual(
self.format.format(datetime.date(2003, 1, 3), 'DDD'),
- _u("003"))
+ u"003")
self.assertEqual(
self.format.format(datetime.date(2003, 12, 31), 'D'),
- _u("365"))
+ u"365")
self.assertEqual(
self.format.format(datetime.date(2003, 12, 31), 'DD'),
- _u("365"))
+ u"365")
self.assertEqual(
self.format.format(datetime.date(2003, 12, 31), 'DDD'),
- _u("365"))
+ u"365")
self.assertEqual(
self.format.format(datetime.date(2004, 12, 31), 'DDD'),
- _u("366"))
+ u"366")
def testFormatDayOfWeekInMOnth(self):
self.assertEqual(
self.format.format(datetime.date(2003, 1, 3), 'F'),
- _u("1"))
+ u"1")
self.assertEqual(
self.format.format(datetime.date(2003, 1, 10), 'F'),
- _u("2"))
+ u"2")
self.assertEqual(
self.format.format(datetime.date(2003, 1, 17), 'F'),
- _u("3"))
+ u"3")
self.assertEqual(
self.format.format(datetime.date(2003, 1, 24), 'F'),
- _u("4"))
+ u"4")
self.assertEqual(
self.format.format(datetime.date(2003, 1, 31), 'F'),
- _u("5"))
+ u"5")
self.assertEqual(
self.format.format(datetime.date(2003, 1, 6), 'F'),
- _u("1"))
+ u"1")
def testFormatUnusualFormats(self):
self.assertEqual(
self.format.format(datetime.date(2003, 1, 3), 'DDD-yyyy'),
- _u("003-2003"))
+ u"003-2003")
self.assertEqual(
self.format.format(datetime.date(2003, 1, 10),
"F. EEEE 'im' MMMM, yyyy"),
- _u("2. Freitag im Januar, 2003"))
+ u"2. Freitag im Januar, 2003")
@@ -1201,13 +1201,3 @@ class TestNumberFormat(TestCase):
# Witout Rounding
self.assertEqual(self.format.format(
decimal.Decimal('0.99999'), '0.###', rounding=False), '0.99999')
-
-
-def test_suite():
- return TestSuite((
- makeSuite(TestDateTimePatternParser),
- makeSuite(TestBuildDateTimeParseInfo),
- makeSuite(TestDateTimeFormat),
- makeSuite(TestNumberPatternParser),
- makeSuite(TestNumberFormat),
- ))
diff --git a/src/zope/i18n/tests/test_gettextmessagecatalog.py b/src/zope/i18n/tests/test_gettextmessagecatalog.py
index edc0c30..07a0932 100644
--- a/src/zope/i18n/tests/test_gettextmessagecatalog.py
+++ b/src/zope/i18n/tests/test_gettextmessagecatalog.py
@@ -13,12 +13,12 @@
##############################################################################
"""Test a gettext implementation of a Message Catalog.
"""
-import unittest, os
+import os
from zope.i18n.gettextmessagecatalog import GettextMessageCatalog
-from zope.i18n.tests.test_imessagecatalog import TestIMessageCatalog
+from zope.i18n.tests import test_imessagecatalog
-class GettextMessageCatalogTest(TestIMessageCatalog):
+class GettextMessageCatalogTest(test_imessagecatalog.TestIMessageCatalog):
def _getMessageCatalog(self):
from zope.i18n import tests
@@ -30,14 +30,3 @@ class GettextMessageCatalogTest(TestIMessageCatalog):
def _getUniqueIndentifier(self):
return self._path
-
-
-
-def test_suite():
- suite = unittest.TestSuite()
- suite.addTest(unittest.makeSuite(GettextMessageCatalogTest))
- return suite
-
-
-if __name__=='__main__':
- unittest.TextTestRunner().run(test_suite())
diff --git a/src/zope/i18n/tests/test_imessagecatalog.py b/src/zope/i18n/tests/test_imessagecatalog.py
index e751eb5..28866e3 100644
--- a/src/zope/i18n/tests/test_imessagecatalog.py
+++ b/src/zope/i18n/tests/test_imessagecatalog.py
@@ -23,10 +23,10 @@ class TestIMessageCatalog(unittest.TestCase):
# This should be overwritten by every class that inherits this test
def _getMessageCatalog(self):
- pass
+ raise NotImplementedError()
def _getUniqueIndentifier(self):
- pass
+ raise NotImplementedError()
def setUp(self):
@@ -64,4 +64,4 @@ class TestIMessageCatalog(unittest.TestCase):
def test_suite():
- return unittest.TestSuite() # Deliberatly empty
+ return unittest.TestSuite() # Deliberately empty
diff --git a/src/zope/i18n/tests/test_itranslationdomain.py b/src/zope/i18n/tests/test_itranslationdomain.py
index 53fda3e..d585be6 100644
--- a/src/zope/i18n/tests/test_itranslationdomain.py
+++ b/src/zope/i18n/tests/test_itranslationdomain.py
@@ -13,7 +13,6 @@
##############################################################################
"""This is an 'abstract' test for the ITranslationDomain interface.
"""
-import sys
import unittest
from zope.interface.verify import verifyObject
from zope.interface import implementer
@@ -25,9 +24,7 @@ from zope.i18n.negotiator import negotiator
from zope.i18n.interfaces import INegotiator, IUserPreferredLanguages
from zope.i18n.interfaces import ITranslationDomain
-PY3 = sys.version_info[0] == 3
-if PY3:
- unicode = str
+text_type = str if bytes is not str else unicode
@implementer(IUserPreferredLanguages)
class Environment(object):
@@ -43,7 +40,7 @@ class TestITranslationDomain(PlacelessSetup):
# This should be overwritten by every class that inherits this test
def _getTranslationDomain(self):
- pass
+ raise NotImplementedError()
def setUp(self):
super(TestITranslationDomain, self).setUp()
@@ -93,7 +90,7 @@ class TestITranslationDomain(PlacelessSetup):
translate = self._domain.translate
translated = translate('no way', target_language='en')
self.assertEqual(translated, "no way")
- self.assertTrue(type(translated) is unicode)
+ self.assertIsInstance(translated, text_type)
def testNoTargetLanguage(self):
translate = self._domain.translate
diff --git a/src/zope/i18n/tests/test_translationdomain.py b/src/zope/i18n/tests/test_translationdomain.py
index baf6aa7..1851a39 100644
--- a/src/zope/i18n/tests/test_translationdomain.py
+++ b/src/zope/i18n/tests/test_translationdomain.py
@@ -13,14 +13,15 @@
##############################################################################
"""This module tests the regular persistent Translation Domain.
"""
-import unittest, os
+import unittest
+import os
from zope.i18n.translationdomain import TranslationDomain
from zope.i18n.gettextmessagecatalog import GettextMessageCatalog
from zope.i18n.tests.test_itranslationdomain import \
TestITranslationDomain, Environment
from zope.i18nmessageid import MessageFactory
from zope.i18n.interfaces import ITranslationDomain
-from .._compat import _u
+
import zope.component
def testdir():
@@ -73,19 +74,19 @@ class TestGlobalTranslationDomain(unittest.TestCase, TestITranslationDomain):
def testEmptyStringTranslate(self):
translate = self._domain.translate
- self.assertEqual(translate(_u(""), target_language='en'), _u(""))
- self.assertEqual(translate(_u(""), target_language='foo'), _u(""))
+ self.assertEqual(translate(u"", target_language='en'), u"")
+ self.assertEqual(translate(u"", target_language='foo'), u"")
def testStringTranslate(self):
self.assertEqual(
- self._domain.translate(_u("short_greeting"), target_language='en'),
- _u("Hello!"))
+ self._domain.translate(u"short_greeting", target_language='en'),
+ u"Hello!")
def testMessageIDTranslate(self):
factory = MessageFactory('default')
translate = self._domain.translate
- msgid = factory(_u("short_greeting"), 'default')
- self.assertEqual(translate(msgid, target_language='en'), _u("Hello!"))
+ msgid = factory(u"short_greeting", 'default')
+ self.assertEqual(translate(msgid, target_language='en'), u"Hello!")
# MessageID attributes override arguments
msgid = factory('43-not-there', 'this ${that} the other',
mapping={'that': 'THAT'})
@@ -96,13 +97,13 @@ class TestGlobalTranslationDomain(unittest.TestCase, TestITranslationDomain):
def testMessageIDRecursiveTranslate(self):
factory = MessageFactory('default')
translate = self._domain.translate
- msgid_sub1 = factory(_u("44-not-there"), '${blue}',
- mapping = {'blue': 'BLUE'})
- msgid_sub2 = factory(_u("45-not-there"), '${yellow}',
- mapping = {'yellow': 'YELLOW'})
+ msgid_sub1 = factory(u"44-not-there", '${blue}',
+ mapping={'blue': 'BLUE'})
+ msgid_sub2 = factory(u"45-not-there", '${yellow}',
+ mapping={'yellow': 'YELLOW'})
mapping = {'color1': msgid_sub1,
'color2': msgid_sub2}
- msgid = factory(_u("46-not-there"), 'Color: ${color1}/${color2}',
+ msgid = factory(u"46-not-there", 'Color: ${color1}/${color2}',
mapping=mapping)
self.assertEqual(
translate(msgid, target_language='en', default="default"),
@@ -111,28 +112,28 @@ class TestGlobalTranslationDomain(unittest.TestCase, TestITranslationDomain):
self.assertEqual(msgid.mapping, {'color1': msgid_sub1,
'color2': msgid_sub2})
# A circular reference should not lead to crashes
- msgid1 = factory(_u("47-not-there"), 'Message 1 and $msg2',
- mapping = {})
- msgid2 = factory(_u("48-not-there"), 'Message 2 and $msg1',
- mapping = {})
+ msgid1 = factory(u"47-not-there", 'Message 1 and $msg2',
+ mapping={})
+ msgid2 = factory(u"48-not-there", 'Message 2 and $msg1',
+ mapping={})
msgid1.mapping['msg2'] = msgid2
msgid2.mapping['msg1'] = msgid1
self.assertRaises(ValueError,
- translate, msgid1, None, None, 'en',"default")
+ translate, msgid1, None, None, 'en', "default")
# Recusrive translations also work if the original message id wasn't a
# message id but a unicode with a directly passed mapping
self.assertEqual("Color: BLUE/YELLOW",
- translate(_u("Color: ${color1}/${color2}"), mapping=mapping,
+ translate(u"Color: ${color1}/${color2}", mapping=mapping,
target_language='en'))
# If we have mapping with a message id from a different domain, make sure
# we use that domain, not ours. If the message domain is not registered yet,
# we should return a defualt translation.
alt_factory = MessageFactory('alt')
- msgid_sub = alt_factory(_u("special"), default=_u("oohhh"))
+ msgid_sub = alt_factory(u"special", default=u"oohhh")
mapping = {'message': msgid_sub}
- msgid = factory(_u("46-not-there"), 'Message: ${message}',
- mapping=mapping)
+ msgid = factory(u"46-not-there", 'Message: ${message}',
+ mapping=mapping)
# test we get a default with no domain registerd
self.assertEqual(
translate(msgid, target_language='en', default="default"),
@@ -162,9 +163,9 @@ class TestGlobalTranslationDomain(unittest.TestCase, TestITranslationDomain):
zope.component.provideUtility(domain, ITranslationDomain, 'alt')
factory = MessageFactory('alt')
- msgid = factory(_u("special"), 'default')
+ msgid = factory(u"special", 'default')
self.assertEqual(
- self._domain.translate(msgid, target_language='en'), _u("Wow"))
+ self._domain.translate(msgid, target_language='en'), u"Wow")
def testSimpleFallbackTranslation(self):
translate = self._domain.translate
@@ -172,11 +173,11 @@ class TestGlobalTranslationDomain(unittest.TestCase, TestITranslationDomain):
# Test that a translation in an unsupported language returns a
# translation in the fallback language (by default, English)
eq(translate('short_greeting', target_language='es'),
- _u("Hello!"))
+ u"Hello!")
# Same test, but use the context argument instead of target_language
context = Environment()
eq(translate('short_greeting', context=context),
- _u("Hello!"))
+ u"Hello!")
def testInterpolationWithoutTranslation(self):
translate = self._domain.translate
@@ -185,12 +186,3 @@ class TestGlobalTranslationDomain(unittest.TestCase, TestITranslationDomain):
default="this ${that} the other",
mapping={"that": "THAT"}),
"this THAT the other")
-
-
-def test_suite():
- suite = unittest.TestSuite()
- suite.addTest(unittest.makeSuite(TestGlobalTranslationDomain))
- return suite
-
-if __name__ == '__main__':
- unittest.main(defaultTest='test_suite')
diff --git a/src/zope/i18n/tests/test_zcml.py b/src/zope/i18n/tests/test_zcml.py
index 9693fe6..52ee437 100644
--- a/src/zope/i18n/tests/test_zcml.py
+++ b/src/zope/i18n/tests/test_zcml.py
@@ -13,7 +13,6 @@
##############################################################################
"""Test the gts ZCML namespace directives.
"""
-import sys
import doctest
import os
import shutil
@@ -23,15 +22,13 @@ import unittest
from zope.component import getUtility
from zope.component import queryUtility
from zope.component.testing import PlacelessSetup
+from zope.configuration import xmlconfig
import zope.i18n.tests
from zope.i18n.interfaces import ITranslationDomain
from zope.i18n import config
-from .._compat import _u
-PY3 = sys.version_info[0] == 3
-if PY3:
- unicode = str
+text_type = str if bytes is not str else unicode
template = """\
<configure
@@ -43,10 +40,8 @@ template = """\
class DirectivesTest(PlacelessSetup, unittest.TestCase):
# This test suite needs the [zcml] and [compile] extra dependencies
- level = 2
def setUp(self):
- from zope.configuration import xmlconfig
super(DirectivesTest, self).setUp()
self.context = xmlconfig.file('meta.zcml', zope.i18n)
self.allowed = config.ALLOWED_LANGUAGES
@@ -57,7 +52,6 @@ class DirectivesTest(PlacelessSetup, unittest.TestCase):
config.ALLOWED_LANGUAGES = self.allowed
def testRegisterTranslations(self):
- from zope.configuration import xmlconfig
self.assertTrue(queryUtility(ITranslationDomain) is None)
xmlconfig.string(
template % '''
@@ -69,10 +63,9 @@ class DirectivesTest(PlacelessSetup, unittest.TestCase):
'locale', 'en', 'LC_MESSAGES', 'zope-i18n.mo')
util = getUtility(ITranslationDomain, 'zope-i18n')
self.assertEqual(util._catalogs.get('test'), ['test'])
- self.assertEqual(util._catalogs.get('en'), [unicode(path)])
+ self.assertEqual(util._catalogs.get('en'), [text_type(path)])
def testAllowedTranslations(self):
- from zope.configuration import xmlconfig
self.assertTrue(queryUtility(ITranslationDomain) is None)
config.ALLOWED_LANGUAGES = ('de', 'fr')
xmlconfig.string(
@@ -85,10 +78,9 @@ class DirectivesTest(PlacelessSetup, unittest.TestCase):
'locale', 'de', 'LC_MESSAGES', 'zope-i18n.mo')
util = getUtility(ITranslationDomain, 'zope-i18n')
self.assertEqual(util._catalogs,
- {'test': ['test'], 'de': [unicode(path)]})
+ {'test': ['test'], 'de': [text_type(path)]})
def testRegisterDistributedTranslations(self):
- from zope.configuration import xmlconfig
self.assertTrue(queryUtility(ITranslationDomain, 'zope-i18n') is None)
xmlconfig.string(
template % '''
@@ -109,19 +101,18 @@ class DirectivesTest(PlacelessSetup, unittest.TestCase):
util = getUtility(ITranslationDomain, 'zope-i18n')
self.assertEqual(util._catalogs.get('test'), ['test', 'test'])
self.assertEqual(util._catalogs.get('en'),
- [unicode(path1), unicode(path2)])
+ [text_type(path1), text_type(path2)])
- msg = util.translate(_u("Additional message"), target_language='en')
- self.assertEqual(msg, _u("Additional message translated"))
+ msg = util.translate(u"Additional message", target_language='en')
+ self.assertEqual(msg, u"Additional message translated")
- msg = util.translate(_u("New Domain"), target_language='en')
- self.assertEqual(msg, _u("New Domain translated"))
+ msg = util.translate(u"New Domain", target_language='en')
+ self.assertEqual(msg, u"New Domain translated")
- msg = util.translate(_u("New Language"), target_language='en')
- self.assertEqual(msg, _u("New Language translated"))
+ msg = util.translate(u"New Language", target_language='en')
+ self.assertEqual(msg, u"New Language translated")
def testRegisterAndCompileTranslations(self):
- from zope.configuration import xmlconfig
config.COMPILE_MO_FILES = True
self.assertTrue(queryUtility(ITranslationDomain) is None)
@@ -147,20 +138,19 @@ class DirectivesTest(PlacelessSetup, unittest.TestCase):
''', self.context)
util = getUtility(ITranslationDomain, 'zope-i18n')
self.assertEqual(util._catalogs,
- {'test': ['test'], 'en': [unicode(path)]})
+ {'test': ['test'], 'en': [text_type(path)]})
- msg = util.translate(_u("I'm a newer file"), target_language='en')
- self.assertEqual(msg, _u("I'm a newer file translated"))
+ msg = util.translate(u"I'm a newer file", target_language='en')
+ self.assertEqual(msg, u"I'm a newer file translated")
util = getUtility(ITranslationDomain, 'zope-i18n2')
- msg = util.translate(_u("I'm a new file"), target_language='en')
- self.assertEqual(msg, _u("I'm a new file translated"))
+ msg = util.translate(u"I'm a new file", target_language='en')
+ self.assertEqual(msg, u"I'm a new file translated")
# Reset the mtime of the mo file
os.utime(path, (path_atime, path_mtime))
def testRegisterTranslationsForDomain(self):
- from zope.configuration import xmlconfig
self.assertTrue(queryUtility(ITranslationDomain, 'zope-i18n') is None)
self.assertTrue(queryUtility(ITranslationDomain, 'zope-i18n2') is None)
xmlconfig.string(
@@ -173,13 +163,13 @@ class DirectivesTest(PlacelessSetup, unittest.TestCase):
'locale3', 'en', 'LC_MESSAGES', 'zope-i18n.mo')
util = getUtility(ITranslationDomain, 'zope-i18n')
self.assertEqual(util._catalogs,
- {'test': ['test'], 'en': [unicode(path)]})
+ {'test': ['test'], 'en': [text_type(path)]})
self.assertTrue(queryUtility(ITranslationDomain, 'zope-i18n2') is None)
def test_suite():
return unittest.TestSuite((
- unittest.makeSuite(DirectivesTest),
- doctest.DocFileSuite('configure.txt'),
- ))
+ unittest.defaultTestLoader.loadTestsFromName(__name__),
+ doctest.DocFileSuite('configure.txt'),
+ ))
diff --git a/src/zope/i18n/translationdomain.py b/src/zope/i18n/translationdomain.py
index 415f1ba..eb2f198 100644
--- a/src/zope/i18n/translationdomain.py
+++ b/src/zope/i18n/translationdomain.py
@@ -20,7 +20,7 @@ from zope.i18nmessageid import Message
from zope.i18n import translate, interpolate
from zope.i18n.simpletranslationdomain import SimpleTranslationDomain
from zope.i18n.interfaces import ITranslationDomain, INegotiator
-from ._compat import _u
+
# The configuration should specify a list of fallback languages for the
# site. If a particular catalog for a negotiated language is not available,
@@ -32,11 +32,8 @@ from ._compat import _u
# message in a catalog is not translated, tough luck, you get the msgid.
LANGUAGE_FALLBACKS = ['en']
-PY3 = sys.version_info[0] == 3
-if PY3:
- unicode = str
-
-_EMPTY = _u("")
+text_type = str if bytes is not str else unicode
+_EMPTY = u""
class TranslationDomain(SimpleTranslationDomain):
@@ -116,7 +113,7 @@ class TranslationDomain(SimpleTranslationDomain):
default, context, seen)
if default is None:
- default = unicode(msgid)
+ default = text_type(msgid)
# Get the translation. Use the specified fallbacks if this fails
catalog_names = self._catalogs.get(target_language)
diff --git a/src/zope/i18n/zcml.py b/src/zope/i18n/zcml.py
index 959a58e..39a4a29 100644
--- a/src/zope/i18n/zcml.py
+++ b/src/zope/i18n/zcml.py
@@ -33,7 +33,7 @@ from zope.i18n.gettextmessagecatalog import GettextMessageCatalog
from zope.i18n.testmessagecatalog import TestMessageCatalog
from zope.i18n.translationdomain import TranslationDomain
from zope.i18n.interfaces import ITranslationDomain
-from ._compat import _u
+
logger = logging.getLogger("zope.i18n")
@@ -42,15 +42,15 @@ class IRegisterTranslationsDirective(Interface):
"""Register translations with the global site manager."""
directory = Path(
- title=_u("Directory"),
- description=_u("Directory containing the translations"),
+ title=u"Directory",
+ description=u"Directory containing the translations",
required=True
)
domain = TextLine(
- title=_u("Domain"),
- description=_u("Translation domain to register. If not specified, "
- "all domains found in the directory are registered"),
+ title=u"Domain",
+ description=(u"Translation domain to register. If not specified, "
+ u"all domains found in the directory are registered"),
required=False
)
@@ -104,7 +104,7 @@ def registerTranslations(_context, directory, domain='*'):
domains[name] = {}
domains[name][language] = domain_path
if loaded:
- logger.debug('register directory %s' % directory)
+ logger.debug('register directory %s', directory)
# Now create TranslationDomain objects and add them as utilities
for name, langs in domains.items():
@@ -115,13 +115,13 @@ def registerTranslations(_context, directory, domain='*'):
# `zope.component.zcml.utility`) since we need the actual utilities
# in place before the merging can be done...
_context.action(
- discriminator = None,
- callable = handler,
- args = (catalogs, name))
+ discriminator=None,
+ callable=handler,
+ args=(catalogs, name))
# also register the interface for the translation utilities
provides = ITranslationDomain
_context.action(
- discriminator = None,
- callable = provideInterface,
- args = (provides.__module__ + '.' + provides.getName(), provides))
+ discriminator=None,
+ callable=provideInterface,
+ args=(provides.__module__ + '.' + provides.getName(), provides))
diff --git a/tox.ini b/tox.ini
index cd5b081..f9b40c5 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,32 +1,22 @@
[tox]
-envlist = py27,py34,py35,py36,pypy,pypy3,coverage,docs
+envlist =
+ py27,py34,py35,py36,pypy,pypy3,coverage,docs
[testenv]
-# We need to use develop egg to get namespace directories right.
-usedevelop = true
commands =
- python setup.py -q test -q
+ zope-testrunner --test-path=src []
+ sphinx-build -b doctest -d {envdir}/doctrees docs {envdir}/doctest
deps =
- python-gettext
- pytz
- zope.component
- zope.configuration
- zope.i18nmessageid
- zope.location
- zope.proxy
- zope.schema
- zope.security
- zope.testing
- zope.testrunner
+ .[test,docs,compile]
[testenv:coverage]
+usedevelop = true
basepython =
- python2.7
+ python3.6
commands =
- coverage erase
- coverage run --source=src setup.py -q test -q
- coverage report --show-missing
- coverage xml
+ coverage run -m zope.testrunner --test-path=src []
+ coverage run -a -m sphinx -b doctest -d {envdir}/.cache/doctrees docs {envdir}/.cache/doctest
+ coverage report --fail-under=97
deps =
{[testenv]deps}
coverage
@@ -36,7 +26,3 @@ basepython =
python2.7
commands =
sphinx-build -b html -d docs/_build/doctrees docs docs/_build/html
- sphinx-build -b doctest -d docs/_build/doctrees docs docs/_build/doctest
-deps =
- {[testenv]deps}
- Sphinx