summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Howitz <mh@gocept.com>2023-01-16 08:27:33 +0100
committerGitHub <noreply@github.com>2023-01-16 08:27:33 +0100
commit29f0dee5316b5527f2b8e6bed78026fea5d07eb1 (patch)
tree7250eba740226c024c491c75bd9a4bf60564e883
parentc34ead9e8a88f88ee25b67a37cebcacc5d4fa959 (diff)
downloadzope-i18n-29f0dee5316b5527f2b8e6bed78026fea5d07eb1.tar.gz
Config with pure python template (#55)
* Drop support for Python 2.7, 3.5, 3.6. * Add support for Python 3.11.
-rw-r--r--.github/workflows/tests.yml20
-rw-r--r--.gitignore1
-rw-r--r--.meta.toml5
-rw-r--r--CHANGES.rst10
-rw-r--r--CONTRIBUTING.md23
-rw-r--r--MANIFEST.in1
-rw-r--r--setup.cfg14
-rw-r--r--setup.py28
-rw-r--r--src/zope/i18n/__init__.py13
-rw-r--r--src/zope/i18n/_compat.py8
-rw-r--r--src/zope/i18n/compile.py14
-rw-r--r--src/zope/i18n/config.py1
-rw-r--r--src/zope/i18n/format.py84
-rw-r--r--src/zope/i18n/gettextmessagecatalog.py8
-rw-r--r--src/zope/i18n/interfaces/__init__.py44
-rw-r--r--src/zope/i18n/interfaces/locales.py487
-rw-r--r--src/zope/i18n/locales/__init__.py67
-rw-r--r--src/zope/i18n/locales/inheritance.py17
-rw-r--r--src/zope/i18n/locales/provider.py4
-rw-r--r--src/zope/i18n/locales/tests/test_docstrings.py2
-rw-r--r--src/zope/i18n/locales/tests/test_fallbackcollator.py2
-rw-r--r--src/zope/i18n/locales/tests/test_locales.py10
-rw-r--r--src/zope/i18n/locales/tests/test_xmlfactory.py5
-rw-r--r--src/zope/i18n/locales/xmlfactory.py48
-rw-r--r--src/zope/i18n/negotiator.py3
-rw-r--r--src/zope/i18n/simpletranslationdomain.py11
-rw-r--r--src/zope/i18n/testing.py3
-rw-r--r--src/zope/i18n/testmessagecatalog.py10
-rw-r--r--src/zope/i18n/tests/locale3/en/LC_MESSAGES/zope-i18n2.mobin0 -> 291 bytes
-rw-r--r--src/zope/i18n/tests/test.py6
-rw-r--r--src/zope/i18n/tests/test_compile.py8
-rw-r--r--src/zope/i18n/tests/test_formats.py81
-rw-r--r--src/zope/i18n/tests/test_gettextmessagecatalog.py1
-rw-r--r--src/zope/i18n/tests/test_imessagecatalog.py4
-rw-r--r--src/zope/i18n/tests/test_itranslationdomain.py17
-rw-r--r--src/zope/i18n/tests/test_negotiator.py11
-rw-r--r--src/zope/i18n/tests/test_plurals.py25
-rw-r--r--src/zope/i18n/tests/test_simpletranslationdomain.py10
-rw-r--r--src/zope/i18n/tests/test_testmessagecatalog.py6
-rw-r--r--src/zope/i18n/tests/test_translationdomain.py61
-rw-r--r--src/zope/i18n/tests/test_zcml.py37
-rw-r--r--src/zope/i18n/tests/testi18nawareobject.py7
-rw-r--r--src/zope/i18n/translationdomain.py19
-rw-r--r--src/zope/i18n/zcml.py15
-rw-r--r--tox.ini32
45 files changed, 667 insertions, 616 deletions
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index d31f648..2ca497a 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -17,32 +17,30 @@ jobs:
fail-fast: false
matrix:
os:
- - ubuntu
+ - ["ubuntu", "ubuntu-20.04"]
config:
# [Python version, tox env]
- ["3.9", "lint"]
- - ["2.7", "py27"]
- - ["3.5", "py35"]
- - ["3.6", "py36"]
- ["3.7", "py37"]
- ["3.8", "py38"]
- ["3.9", "py39"]
- ["3.10", "py310"]
- - ["pypy2", "pypy"]
- - ["pypy3", "pypy3"]
+ - ["3.11", "py311"]
+ - ["pypy-3.7", "pypy3"]
- ["3.9", "docs"]
- ["3.9", "coverage"]
- runs-on: ${{ matrix.os }}-latest
+ runs-on: ${{ matrix.os[1] }}
+ if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name
name: ${{ matrix.config[1] }}
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v3
- name: Set up Python
- uses: actions/setup-python@v2
+ uses: actions/setup-python@v4
with:
python-version: ${{ matrix.config[0] }}
- name: Pip cache
- uses: actions/cache@v2
+ uses: actions/cache@v3
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ matrix.config[0] }}-${{ hashFiles('setup.*', 'tox.ini') }}
@@ -58,7 +56,7 @@ jobs:
- name: Coverage
if: matrix.config[1] == 'coverage'
run: |
- pip install coveralls coverage-python-version
+ pip install coveralls
coveralls --service=github
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.gitignore b/.gitignore
index c724a76..1f321f5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -28,4 +28,5 @@ lib64
log/
parts/
pyvenv.cfg
+testing.log
var/
diff --git a/.meta.toml b/.meta.toml
index 492325b..11d26ca 100644
--- a/.meta.toml
+++ b/.meta.toml
@@ -2,15 +2,15 @@
# https://github.com/zopefoundation/meta/tree/master/config/pure-python
[meta]
template = "pure-python"
-commit-id = "fba6d957ba447b6fa369d872e803756bd5176391"
+commit-id = "d03ad585"
[python]
with-windows = false
with-pypy = true
with-future-python = false
-with-legacy-python = true
with-docs = true
with-sphinx-doctests = true
+with-macos = false
[tox]
use-flake8 = true
@@ -40,6 +40,7 @@ ignore-bad-ideas = [
"src/zope/i18n/tests/locale/en/LC_MESSAGES/zope-i18n.mo",
"src/zope/i18n/tests/locale2/en/LC_MESSAGES/zope-i18n.mo",
"src/zope/i18n/tests/locale3/en/LC_MESSAGES/zope-i18n.mo",
+ "src/zope/i18n/tests/locale3/en/LC_MESSAGES/zope-i18n2.mo",
"src/zope/i18n/tests/pl-default.mo",
"src/zope/i18n/tests/sr-default.mo",
"src/zope/i18n/tests/sr@Cyrl-default.mo",
diff --git a/CHANGES.rst b/CHANGES.rst
index f6ff6ea..681b65c 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -2,10 +2,14 @@
CHANGES
=========
-4.9.1 (unreleased)
-==================
+5.0 (unreleased)
+================
+
+- Add support for Python 3.11.
+
+- Drop support for Python 2.7, 3.5, 3.6.
-- Nothing changed yet.
+- Drop deprecated support for running the tests using ``python setup.py test``.
4.9.0 (2021-12-09)
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000..31d95f0
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,23 @@
+<!--
+Generated from:
+https://github.com/zopefoundation/meta/tree/master/config/pure-python
+-->
+# Contributing to zopefoundation projects
+
+The projects under the zopefoundation GitHub organization are open source and
+welcome contributions in different forms:
+
+* bug reports
+* code improvements and bug fixes
+* documentation improvements
+* pull request reviews
+
+For any changes in the repository besides trivial typo fixes you are required
+to sign the contributor agreement. See
+https://www.zope.dev/developer/becoming-a-committer.html for details.
+
+Please visit our [Developer
+Guidelines](https://www.zope.dev/developer/guidelines.html) if you'd like to
+contribute code changes and our [guidelines for reporting
+bugs](https://www.zope.dev/developer/reporting-bugs.html) if you want to file a
+bug report.
diff --git a/MANIFEST.in b/MANIFEST.in
index b2b9c96..4a04ff5 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -1,5 +1,6 @@
# Generated from:
# https://github.com/zopefoundation/meta/tree/master/config/pure-python
+include *.md
include *.rst
include *.txt
include buildout.cfg
diff --git a/setup.cfg b/setup.cfg
index e159e42..ff2d6e9 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,7 +1,7 @@
# Generated from:
# https://github.com/zopefoundation/meta/tree/master/config/pure-python
[bdist_wheel]
-universal = 1
+universal = 0
[flake8]
doctests = 1
@@ -20,7 +20,19 @@ ignore-bad-ideas =
src/zope/i18n/tests/locale/en/LC_MESSAGES/zope-i18n.mo
src/zope/i18n/tests/locale2/en/LC_MESSAGES/zope-i18n.mo
src/zope/i18n/tests/locale3/en/LC_MESSAGES/zope-i18n.mo
+ src/zope/i18n/tests/locale3/en/LC_MESSAGES/zope-i18n2.mo
src/zope/i18n/tests/pl-default.mo
src/zope/i18n/tests/sr-default.mo
src/zope/i18n/tests/sr@Cyrl-default.mo
src/zope/i18n/tests/sr@Latn-default.mo
+
+[isort]
+force_single_line = True
+combine_as_imports = True
+sections = FUTURE,STDLIB,THIRDPARTY,ZOPE,FIRSTPARTY,LOCALFOLDER
+known_third_party = six, docutils, pkg_resources
+known_zope =
+known_first_party =
+default_section = ZOPE
+line_length = 79
+lines_after_imports = 2
diff --git a/setup.py b/setup.py
index 9861989..a2a4ae8 100644
--- a/setup.py
+++ b/setup.py
@@ -19,7 +19,9 @@
"""Setup for zope.i18n package
"""
import os
-from setuptools import setup, find_packages
+
+from setuptools import find_packages
+from setuptools import setup
def read(*rnames):
@@ -27,21 +29,6 @@ def read(*rnames):
return f.read()
-def alltests():
- import sys
- import unittest
- # use the zope.testrunner machinery to find all the
- # test suites we've put under ourselves
- import zope.testrunner.find
- import zope.testrunner.options
- here = os.path.abspath(os.path.join(os.path.dirname(__file__), 'src'))
- args = sys.argv[:]
- defaults = ["--test-path", here]
- options = zope.testrunner.options.get_options(args, defaults)
- suites = list(zope.testrunner.find.find_suites(options))
- return unittest.TestSuite(suites)
-
-
COMPILE_REQUIRES = [
# python-gettext used to be here, but it's now
# a fixed requirement. Keep the extra to avoid
@@ -62,7 +49,7 @@ TESTS_REQUIRE = COMPILE_REQUIRES + ZCML_REQUIRES + [
setup(
name='zope.i18n',
- version='4.9.1.dev0',
+ version='5.0.dev0',
author='Zope Foundation and Contributors',
author_email='zope-dev@zope.org',
description='Zope Internationalization Support',
@@ -80,15 +67,12 @@ setup(
'Intended Audience :: Developers',
'License :: OSI Approved :: Zope Public License',
'Programming Language :: Python',
- 'Programming Language :: Python :: 2',
- 'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
- 'Programming Language :: Python :: 3.5',
- 'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: 3.8',
'Programming Language :: Python :: 3.9',
'Programming Language :: Python :: 3.10',
+ 'Programming Language :: Python :: 3.11',
'Programming Language :: Python :: Implementation :: CPython',
'Programming Language :: Python :: Implementation :: PyPy',
'Natural Language :: English',
@@ -118,8 +102,6 @@ setup(
'repoze.sphinx.autointerface',
],
},
- 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 b737d00..36b6953 100644
--- a/src/zope/i18n/__init__.py
+++ b/src/zope/i18n/__init__.py
@@ -16,16 +16,15 @@
import re
from zope.component import queryUtility
-from zope.i18nmessageid import Message
# MessageFactory is not used, but it might be here for BBB reasons,
# as it could be imported by other packages.
+from zope.i18nmessageid import Message
from zope.i18nmessageid import MessageFactory # noqa
-from zope.i18n._compat import text_type
from zope.i18n.config import ALLOWED_LANGUAGES
+from zope.i18n.interfaces import IFallbackTranslationDomainFactory
from zope.i18n.interfaces import INegotiator
from zope.i18n.interfaces import ITranslationDomain
-from zope.i18n.interfaces import IFallbackTranslationDomainFactory
# Set up regular expressions for finding interpolation variables in text.
@@ -37,7 +36,7 @@ _interp_regex = re.compile(r'(?<!\$)(\$(?:(%(n)s)|{(%(n)s)}))'
% ({'n': NAME_RE}))
-class _FallbackNegotiator(object):
+class _FallbackNegotiator:
def getLanguage(self, _allowed, _context):
return None
@@ -171,9 +170,9 @@ def translate(msgid, domain=None, mapping=None, context=None,
number = msgid.number
if default is None:
- default = text_type(msgid)
+ default = str(msgid)
if msgid_plural is not None and default_plural is None:
- default_plural = text_type(msgid_plural)
+ default_plural = str(msgid_plural)
if domain:
util = queryUtility(ITranslationDomain, domain)
@@ -239,7 +238,7 @@ def interpolate(text, mapping=None):
value = mapping.get(param1 or param2, whole)
if isinstance(value, Message):
value = interpolate(value, value.mapping)
- return text_type(value)
+ return str(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 f6bf93b..0000000
--- a/src/zope/i18n/_compat.py
+++ /dev/null
@@ -1,8 +0,0 @@
-# This gives a linting error because unicode is not defined on Python 3:
-# text_type = str if bytes is not str else unicode
-try:
- # Python 2
- text_type = unicode
-except NameError:
- # Python 3
- text_type = str
diff --git a/src/zope/i18n/compile.py b/src/zope/i18n/compile.py
index 81a6a17..5a5564f 100644
--- a/src/zope/i18n/compile.py
+++ b/src/zope/i18n/compile.py
@@ -1,11 +1,12 @@
-from contextlib import closing
+import logging
import os.path
+from contextlib import closing
from os.path import join
-import logging
from pythongettext.msgfmt import Msgfmt
from pythongettext.msgfmt import PoSyntaxError
+
logger = logging.getLogger('zope.i18n')
@@ -15,7 +16,7 @@ HAS_PYTHON_GETTEXT = True
def _safe_mtime(path):
try:
return os.path.getmtime(path)
- except (IOError, OSError):
+ except OSError:
return None
@@ -36,10 +37,7 @@ def compile_mo_file(domain, lc_messages_path):
if po_mtime > mo_mtime:
try:
- # Msgfmt.getAsFile returns io.BytesIO on Python 3,
- # and cStringIO.StringIO on Python 2;
- # sadly StringIO isn't a proper context manager, so we have to
- # wrap it with `closing`. Also, Msgfmt doesn't properly close a
+ # Msgfmt doesn't properly close a
# file it opens for reading if you pass the path,
# but it does if you pass the file.
with open(pofile, 'rb') as pofd:
@@ -49,5 +47,5 @@ def compile_mo_file(domain, lc_messages_path):
except PoSyntaxError as err:
logger.warning(
'Syntax error while compiling %s (%s).', pofile, err.msg)
- except (IOError, OSError) as err:
+ except OSError as err:
logger.warning('Error while compiling %s (%s).', pofile, err)
diff --git a/src/zope/i18n/config.py b/src/zope/i18n/config.py
index ce94ded..1979d26 100644
--- a/src/zope/i18n/config.py
+++ b/src/zope/i18n/config.py
@@ -1,5 +1,6 @@
import os
+
#: The environment variable that is consulted when this module
#: is imported to determine the value of `COMPILE_MO_FILES`.
#: Simply set this to a non-empty string to make it True.
diff --git a/src/zope/i18n/format.py b/src/zope/i18n/format.py
index 2a2421c..8162978 100644
--- a/src/zope/i18n/format.py
+++ b/src/zope/i18n/format.py
@@ -16,23 +16,17 @@
This module implements basic object formatting functionality, such as
date/time, number and money formatting.
"""
-import sys
-import re
-import math
import datetime
+import math
+import re
+import sys
+
import pytz
import pytz.reference
-
-from zope.i18n._compat import text_type
-from zope.i18n.interfaces import IDateTimeFormat, INumberFormat
from zope.interface import implementer
-
-NATIVE_NUMBER_TYPES = (int, float)
-try:
- NATIVE_NUMBER_TYPES += (long,)
-except NameError:
- pass # Py3
+from zope.i18n.interfaces import IDateTimeFormat
+from zope.i18n.interfaces import INumberFormat
def roundHalfUp(n):
@@ -55,7 +49,7 @@ class DateTimeParseError(Exception):
@implementer(IDateTimeFormat)
-class DateTimeFormat(object):
+class DateTimeFormat:
__doc__ = IDateTimeFormat.__doc__
_DATETIMECHARS = "aGyMdEDFwWhHmsSkKz"
@@ -212,7 +206,7 @@ class DateTimeFormat(object):
else:
bin_pattern = self._bin_pattern
- text = u""
+ text = ""
info = buildDateTimeInfo(obj, self.calendar, bin_pattern)
for elem in bin_pattern:
text += info.get(elem, elem)
@@ -226,7 +220,7 @@ class NumberParseError(Exception):
@implementer(INumberFormat)
-class NumberFormat(object):
+class NumberFormat:
__doc__ = INumberFormat.__doc__
type = None
@@ -236,18 +230,18 @@ 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": ".",
+ "group": ",",
+ "list": ";",
+ "percentSign": "%",
+ "nativeZeroDigit": "0",
+ "patternDigit": "#",
+ "plusSign": "+",
+ "minusSign": "-",
+ "exponential": "E",
+ "perMille": "\xe2\x88\x9e",
+ "infinity": "\xef\xbf\xbd",
+ "nan": ''
}
self.symbols.update(symbols)
if pattern is not None:
@@ -411,12 +405,7 @@ class NumberFormat(object):
else:
bin_pattern = bin_pattern[1]
- if isinstance(obj, NATIVE_NUMBER_TYPES):
- # repr() handles high-precision numbers correctly in
- # Python 2 and 3. str() is only correct in Python 3.
- strobj = repr(obj)
- else:
- strobj = str(obj)
+ strobj = str(obj)
if 'e' in strobj:
# Str(obj) # returned scientific representation of a number (e.g.
# 1e-7). We can't rely on str() to format fraction.
@@ -432,7 +421,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 = ""
if exp_bin_pattern.startswith('+'):
plus_sign = self.symbols['plusSign']
exp_bin_pattern = exp_bin_pattern[1:]
@@ -510,8 +499,8 @@ class NumberFormat(object):
if bin_pattern[PADDING4] is not None and post_padding > 0:
text += bin_pattern[PADDING4] * post_padding
- # TODO: Need to make sure unicode is everywhere
- return text_type(text)
+ # TODO: Need to make sure str is everywhere
+ return str(text)
DEFAULT = 0
@@ -622,12 +611,13 @@ def buildDateTimeParseInfo(calendar, pattern):
# am/pm marker (Text)
for entry in _findFormattingCharacterInPattern('a', pattern):
- info[entry] = r'(%s|%s)' % (calendar.am, calendar.pm)
+ info[entry] = r'({}|{})'.format(calendar.am, calendar.pm)
# era designator (Text)
# TODO: works for gregorian only right now
for entry in _findFormattingCharacterInPattern('G', pattern):
- info[entry] = r'(%s|%s)' % (calendar.eras[1][1], calendar.eras[2][1])
+ info[entry] = r'({}|{})'.format(
+ calendar.eras[1][1], calendar.eras[2][1])
# time zone (Text)
for entry in _findFormattingCharacterInPattern('z', pattern):
@@ -703,8 +693,8 @@ def buildDateTimeInfo(dt, calendar, pattern):
tz_fullname = getattr(tzinfo, 'zone', None) or tz_name
info = {
- ('y', 2): text_type(dt.year)[2:],
- ('y', 4): text_type(dt.year),
+ ('y', 2): str(dt.year)[2:],
+ ('y', 4): str(dt.year),
}
# Generic Numbers
@@ -715,7 +705,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] = ("%%.%ii" % entry[1]) % value
# am/pm marker (Text)
for entry in _findFormattingCharacterInPattern('a', pattern):
@@ -729,9 +719,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] = "%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] = "%s%.2i:%.2i" % (tz_sign, tz_hours, tz_mins)
elif entry[1] == 3:
info[entry] = tz_name
else:
@@ -740,9 +730,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] = "%i" % dt.month
elif entry[1] == 2:
- info[entry] = u"%.2i" % dt.month
+ info[entry] = "%.2i" % dt.month
elif entry[1] == 3:
info[entry] = calendar.months[dt.month][1]
else:
@@ -751,9 +741,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] = "%i" % weekday
elif entry[1] == 2:
- info[entry] = u"%.2i" % weekday
+ info[entry] = "%.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 8e1272b..85b0687 100644
--- a/src/zope/i18n/gettextmessagecatalog.py
+++ b/src/zope/i18n/gettextmessagecatalog.py
@@ -16,11 +16,13 @@
from functools import wraps
from gettext import GNUTranslations
-from zope.i18n.interfaces import IGlobalMessageCatalog
+
from zope.interface import implementer
+from zope.i18n.interfaces import IGlobalMessageCatalog
+
-class _KeyErrorRaisingFallback(object):
+class _KeyErrorRaisingFallback:
def ugettext(self, message):
raise KeyError(message)
@@ -51,7 +53,7 @@ def plural_formatting(func):
@implementer(IGlobalMessageCatalog)
-class GettextMessageCatalog(object):
+class GettextMessageCatalog:
"""A message catalog based on GNU gettext and Python's gettext module."""
_catalog = None
diff --git a/src/zope/i18n/interfaces/__init__.py b/src/zope/i18n/interfaces/__init__.py
index 025c477..78e5239 100644
--- a/src/zope/i18n/interfaces/__init__.py
+++ b/src/zope/i18n/interfaces/__init__.py
@@ -13,8 +13,12 @@
##############################################################################
"""Internationalization of content objects.
"""
-from zope.interface import Interface, Attribute
-from zope.schema import TextLine, Dict, Choice, Field
+from zope.interface import Attribute
+from zope.interface import Interface
+from zope.schema import Choice
+from zope.schema import Dict
+from zope.schema import Field
+from zope.schema import TextLine
class II18nAware(Interface):
@@ -85,13 +89,13 @@ class IMessageCatalog(Interface):
"""
language = TextLine(
- title=u"Language",
- description=u"The language the catalog translates to.",
+ title="Language",
+ description="The language the catalog translates to.",
required=True)
domain = TextLine(
- title=u"Domain",
- description=u"The domain the catalog is registered for.",
+ title="Domain",
+ description="The domain the catalog is registered for.",
required=True)
def getIdentifier():
@@ -149,8 +153,8 @@ class ITranslationDomain(Interface):
"""
domain = TextLine(
- title=u"Domain Name",
- description=u"The name of the domain this object represents.",
+ title="Domain Name",
+ description="The name of the domain this object represents.",
required=True)
def translate(msgid, mapping=None, context=None, target_language=None,
@@ -177,7 +181,7 @@ class IFallbackTranslationDomainFactory(Interface):
debugging i18n.
"""
- def __call__(domain_id=u""):
+ def __call__(domain_id=""):
"""Return a fallback translation domain for the given domain id.
"""
@@ -379,22 +383,22 @@ class INumberFormat(IFormat):
"""
type = Field(
- 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.")),
+ title="Type",
+ description=("The type into which a string is parsed. If ``None``, "
+ "then ``int`` will be used for whole numbers and "
+ "``float`` for decimals."),
default=None,
required=False)
symbols = Dict(
- title=u"Number Symbols",
+ title="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="Dictionary Class",
+ values=("decimal", "group", "list", "percentSign",
+ "nativeZeroDigit", "patternDigit", "plusSign",
+ "minusSign", "exponential", "perMille",
+ "infinity", "nan")),
+ value_type=TextLine(title="Symbol"))
class IDateTimeFormat(IFormat):
diff --git a/src/zope/i18n/interfaces/locales.py b/src/zope/i18n/interfaces/locales.py
index 01c9cbe..83e40a3 100644
--- a/src/zope/i18n/interfaces/locales.py
+++ b/src/zope/i18n/interfaces/locales.py
@@ -15,10 +15,19 @@
"""
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.interface import Attribute
+from zope.interface import Interface
+from zope.schema import Bool
from zope.schema import Choice
+from zope.schema import Date
+from zope.schema import Dict
+from zope.schema import Field
+from zope.schema import Int
+from zope.schema import List
+from zope.schema import Text
+from zope.schema import TextLine
+from zope.schema import Tuple
class ILocaleProvider(Interface):
@@ -66,35 +75,35 @@ class ILocaleIdentity(Interface):
"""
language = TextLine(
- title=u"Language Type",
- description=u"The language for which a locale is applicable.",
+ title="Language Type",
+ description="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="Script Type",
+ description=("""The script for which the language/locale is
applicable."""),
constraint=re.compile(r'[a-z]*').match)
territory = TextLine(
- title=u"Territory Type",
- description=u"The territory for which a locale is applicable.",
+ title="Territory Type",
+ description="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.",
+ title="Variant Type",
+ description="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.",
+ title="Locale Version",
+ description="The value of this field is an ILocaleVersion object.",
readonly=True)
def __repr__(self):
@@ -109,21 +118,21 @@ class ILocaleVersion(Interface):
"""
number = TextLine(
- title=u"Version Number",
- description=u"The version number of the locale.",
+ title="Version Number",
+ description="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.",
+ title="Generation Date",
+ description="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.",
+ title="Notes",
+ description="Some release notes for the version of this locale.",
readonly=True)
@@ -136,34 +145,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="Language type to translated name",
+ key_type=TextLine(title="Language Type"),
+ value_type=TextLine(title="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="Script type to script name",
+ key_type=TextLine(title="Script Type"),
+ value_type=TextLine(title="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="Territory type to translated territory name",
+ key_type=TextLine(title="Territory Type"),
+ value_type=TextLine(title="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="Variant type to name",
+ key_type=TextLine(title="Variant Type"),
+ value_type=TextLine(title="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="Key type to name",
+ key_type=TextLine(title="Key Type"),
+ value_type=TextLine(title="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="Type type and key to localized name",
+ key_type=Tuple(title="Type Type and Key"),
+ value_type=TextLine(title="Type Name"))
class ILocaleTimeZone(Interface):
@@ -176,25 +185,25 @@ class ILocaleTimeZone(Interface):
"""
type = TextLine(
- title=u"Time Zone Type",
- description=u"Standard name of the timezone for unique referencing.",
+ title="Time Zone Type",
+ description="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"),
+ title="Cities",
+ description="Cities in Timezone",
+ value_type=TextLine(title="City Name"),
required=True,
readonly=True)
names = Dict(
- title=u"Time Zone Names",
- description=u"Various names of the timezone.",
+ title="Time Zone Names",
+ description="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",
+ title="Time Zone Name Type",
+ values=("generic", "standard", "daylight")),
+ value_type=Tuple(title="Time Zone Name and Abbreviation",
min_length=2, max_length=2),
required=True,
readonly=True)
@@ -204,20 +213,20 @@ 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",
+ title="Format Type",
+ description="The name of the format",
required=False,
readonly=True)
displayName = TextLine(
- title=u"Display Name",
- description=u"Name of the calendar, for example 'gregorian'.",
+ title="Display Name",
+ description="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.",
+ title="Format Pattern",
+ description="The pattern that is used to format the object.",
required=True,
readonly=True)
@@ -226,22 +235,22 @@ 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="Format Length Type",
+ description="Name of the format length",
+ values=("full", "long", "medium", "short")
)
default = TextLine(
- title=u"Default Format",
- description=u"The name of the defaulkt format.")
+ title="Default Format",
+ description="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"),
+ title="Formats",
+ description="Maps format types to format objects",
+ key_type=TextLine(title="Format Type"),
value_type=Field(
- title=u"Format Object",
- description=u"Values are ILocaleFormat objects."),
+ title="Format Object",
+ description="Values are ILocaleFormat objects."),
required=True,
readonly=True)
@@ -250,24 +259,24 @@ 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="Month context type",
+ description="Name of the month context, format or stand-alone.")
defaultWidth = TextLine(
- title=u"Default month name width",
- default=u"wide")
+ title="Default month name width",
+ default="wide")
months = Dict(
- title=u"Month Names",
- description=(u"A mapping of month name widths to a mapping of"
- u"corresponding month names."),
+ title="Month Names",
+ description=("A mapping of month name widths to a mapping of"
+ "corresponding month names."),
key_type=Choice(
- title=u"Width type",
- values=(u"wide", u"abbreviated", u"narrow")),
+ title="Width type",
+ values=("wide", "abbreviated", "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="Month name",
+ key_type=Int(title="Type", min=1, max=12),
+ value_type=TextLine(title="Month Name"))
)
@@ -275,27 +284,27 @@ 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="Day context type",
+ description="Name of the day context, format or stand-alone.")
defaultWidth = TextLine(
- title=u"Default day name width",
- default=u"wide")
+ title="Default day name width",
+ default="wide")
days = Dict(
- title=u"Day Names",
- description=(u"A mapping of day name widths to a mapping of"
- u"corresponding day names."),
+ title="Day Names",
+ description=("A mapping of day name widths to a mapping of"
+ "corresponding day names."),
key_type=Choice(
- title=u"Width type",
- values=(u"wide", u"abbreviated", u"narrow")),
+ title="Width type",
+ values=("wide", "abbreviated", "narrow")),
value_type=Dict(
- title=u"Day name",
+ title="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="Type",
+ values=("sun", "mon", "tue", "wed",
+ "thu", "fri", "sat")),
+ value_type=TextLine(title="Day Name"))
)
@@ -304,57 +313,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="Calendar Type",
+ description="Name of the calendar, for example 'gregorian'.")
defaultMonthContext = TextLine(
- title=u"Default month context",
- default=u"format")
+ title="Default month context",
+ default="format")
monthContexts = Dict(
- 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"))
+ title="Month Contexts",
+ description=("A mapping of month context types to "
+ "ILocaleMonthContext objects"),
+ key_type=Choice(title="Type",
+ values=("format", "stand-alone")),
+ value_type=Field(title="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",
+ title="Month Names",
+ description="A mapping of all month names and abbreviations",
+ key_type=Int(title="Type", min=1, max=12),
+ value_type=Tuple(title="Month Name and Abbreviation",
min_length=2, max_length=2))
defaultDayContext = TextLine(
- title=u"Default day context",
- default=u"format")
+ title="Default day context",
+ default="format")
dayContexts = Dict(
- 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"))
+ title="Day Contexts",
+ description=("A mapping of day context types to "
+ "ILocaleDayContext objects"),
+ key_type=Choice(title="Type",
+ values=("format", "stand-alone")),
+ value_type=Field(title="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",
+ title="Weekdays Names",
+ description="A mapping of all month names and abbreviations",
+ key_type=Choice(title="Type",
+ values=("sun", "mon", "tue", "wed",
+ "thu", "fri", "sat")),
+ value_type=Tuple(title="Weekdays Name and Abbreviation",
min_length=2, max_length=2))
week = Dict(
- title=u"Week Information",
- description=u"Contains various week information",
+ title="Week Information",
+ description="Contains various week information",
key_type=Choice(
- title=u"Type",
- description=(u"""
+ title="Type",
+ description=("""
Varies Week information:
- 'minDays' is just an integer between 1 and 7.
@@ -364,51 +373,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=("minDays", "firstDay",
+ "weekendStart", "weekendEnd")))
- am = TextLine(title=u"AM String")
+ am = TextLine(title="AM String")
- pm = TextLine(title=u"PM String")
+ pm = TextLine(title="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",
+ title="Era Names",
+ key_type=Int(title="Type", min=0),
+ value_type=Tuple(title="Era Name and Abbreviation",
min_length=2, max_length=2))
- defaultDateFormat = TextLine(title=u"Default Date Format Type")
+ defaultDateFormat = TextLine(title="Default Date Format Type")
dateFormats = Dict(
- title=u"Date Formats",
- description=u"Contains various Date Formats.",
+ title="Date Formats",
+ description="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="Type",
+ description="Name of the format length",
+ values=("full", "long", "medium", "short")),
+ value_type=Field(title="ILocaleFormatLength object"))
- defaultTimeFormat = TextLine(title=u"Default Time Format Type")
+ defaultTimeFormat = TextLine(title="Default Time Format Type")
timeFormats = Dict(
- title=u"Time Formats",
- description=u"Contains various Time Formats.",
+ title="Time Formats",
+ description="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="Type",
+ description="Name of the format length",
+ values=("full", "long", "medium", "short")),
+ value_type=Field(title="ILocaleFormatLength object"))
- defaultDateTimeFormat = TextLine(title=u"Default Date-Time Format Type")
+ defaultDateTimeFormat = TextLine(title="Default Date-Time Format Type")
dateTimeFormats = Dict(
- title=u"Date-Time Formats",
- description=u"Contains various Date-Time Formats.",
+ title="Date-Time Formats",
+ description="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="Type",
+ description="Name of the format length",
+ values=("full", "long", "medium", "short")),
+ value_type=Field(title="ILocaleFormatLength object"))
def getMonthNames():
"""Return a list of month names."""
@@ -445,30 +454,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="Localized Pattern Characters",
+ description="Localized pattern characters used in dates and times")
calendars = Dict(
- title=u"Calendar type to ILocaleCalendar",
+ title="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="Calendar Type",
+ values=("gregorian",
+ "arabic",
+ "chinese",
+ "civil-arabic",
+ "hebrew",
+ "japanese",
+ "thai-buddhist")),
+ value_type=Field(title="Calendar",
+ description="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="Time zone type to ILocaleTimezone",
+ key_type=TextLine(title="Time Zone type"),
+ value_type=Field(title="Time Zone",
+ description="This is a ILocaleTimeZone object."))
- def getFormatter(category, length=None, name=None, calendar=u"gregorian"):
+ def getFormatter(category, length=None, name=None, calendar="gregorian"):
"""Get a date/time formatter.
`category` must be one of 'date', 'dateTime', 'time'.
@@ -482,81 +491,81 @@ class ILocaleDates(Interface):
class ILocaleCurrency(Interface):
"""Defines a particular currency."""
- type = TextLine(title=u"Type")
+ type = TextLine(title="Type")
- symbol = TextLine(title=u"Symbol")
+ symbol = TextLine(title="Symbol")
- displayName = TextLine(title=u"Official Name")
+ displayName = TextLine(title="Official Name")
- symbolChoice = Bool(title=u"Symbol Choice")
+ symbolChoice = Bool(title="Symbol Choice")
class ILocaleNumbers(Interface):
"""This object contains various data about numbers and currencies."""
symbols = Dict(
- title=u"Number Symbols",
+ title="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="Format Name",
+ values=("decimal", "group", "list", "percentSign",
+ "nativeZeroDigit", "patternDigit", "plusSign",
+ "minusSign", "exponential", "perMille",
+ "infinity", "nan")),
+ value_type=TextLine(title="Symbol"))
- defaultDecimalFormat = TextLine(title=u"Default Decimal Format Type")
+ defaultDecimalFormat = TextLine(title="Default Decimal Format Type")
decimalFormats = Dict(
- title=u"Decimal Formats",
- description=u"Contains various Decimal Formats.",
+ title="Decimal Formats",
+ description="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="Type",
+ description="Name of the format length",
+ values=("full", "long", "medium", "short")),
+ value_type=Field(title="ILocaleFormatLength object"))
- defaultScientificFormat = TextLine(title=u"Default Scientific Format Type")
+ defaultScientificFormat = TextLine(title="Default Scientific Format Type")
scientificFormats = Dict(
- title=u"Scientific Formats",
- description=u"Contains various Scientific Formats.",
+ title="Scientific Formats",
+ description="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="Type",
+ description="Name of the format length",
+ values=("full", "long", "medium", "short")),
+ value_type=Field(title="ILocaleFormatLength object"))
- defaultPercentFormat = TextLine(title=u"Default Percent Format Type")
+ defaultPercentFormat = TextLine(title="Default Percent Format Type")
percentFormats = Dict(
- title=u"Percent Formats",
- description=u"Contains various Percent Formats.",
+ title="Percent Formats",
+ description="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="Type",
+ description="Name of the format length",
+ values=("full", "long", "medium", "short")),
+ value_type=Field(title="ILocaleFormatLength object"))
- defaultCurrencyFormat = TextLine(title=u"Default Currency Format Type")
+ defaultCurrencyFormat = TextLine(title="Default Currency Format Type")
currencyFormats = Dict(
- title=u"Currency Formats",
- description=u"Contains various Currency Formats.",
+ title="Currency Formats",
+ description="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="Type",
+ description="Name of the format length",
+ values=("full", "long", "medium", "short")),
+ value_type=Field(title="ILocaleFormatLength object"))
currencies = Dict(
- title=u"Currencies",
- description=u"Contains various Currency data.",
+ title="Currencies",
+ description="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="Type",
+ description="Name of the format length"),
+ value_type=Field(title="ILocaleCurrency object"))
- def getFormatter(category, length=None, name=u""):
+ def getFormatter(category, length=None, name=""):
"""Get the NumberFormat based on the category, length and name of the
format.
@@ -577,23 +586,23 @@ class ILocaleNumbers(Interface):
"""Get the default currency."""
-_orientations = [u"left-to-right", u"right-to-left",
- u"top-to-bottom", u"bottom-to-top"]
+_orientations = ["left-to-right", "right-to-left",
+ "top-to-bottom", "bottom-to-top"]
class ILocaleOrientation(Interface):
"""Information about the orientation of text."""
characters = Choice(
- title=u"Orientation of characters",
+ title="Orientation of characters",
values=_orientations,
- default=u"left-to-right"
+ default="left-to-right"
)
lines = Choice(
- title=u"Orientation of characters",
+ title="Orientation of characters",
values=_orientations,
- default=u"top-to-bottom"
+ default="top-to-bottom"
)
@@ -610,39 +619,39 @@ class ILocale(Interface):
"""
id = Field(
- title=u"Locale identity",
- description=u"ILocaleIdentity object identifying the locale.",
+ title="Locale identity",
+ description="ILocaleIdentity object identifying the locale.",
required=True,
readonly=True)
displayNames = Field(
- title=u"Display Names",
- description=(u"""ILocaleDisplayNames object that contains localized
+ title="Display Names",
+ description=("""ILocaleDisplayNames object that contains localized
names."""))
dates = Field(
- title=u"Dates",
- description=u"ILocaleDates object that contains date/time data.")
+ title="Dates",
+ description="ILocaleDates object that contains date/time data.")
numbers = Field(
- title=u"Numbers",
- description=u"ILocaleNumbers object that contains number data.")
+ title="Numbers",
+ description="ILocaleNumbers object that contains number data.")
orientation = Field(
- title=u"Orientation",
- description=u"ILocaleOrientation with text orientation info.")
+ title="Orientation",
+ description="ILocaleOrientation with text orientation info.")
delimiters = Dict(
- title=u"Delimiters",
- description=u"Contains various Currency data.",
+ title="Delimiters",
+ description="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="Delimiter Type",
+ description="Delimiter name.",
+ values=("quotationStart",
+ "quotationEnd",
+ "alternateQuotationStart",
+ "alternateQuotationEnd")),
+ value_type=Field(title="Delimiter symbol"))
def getLocaleID():
"""Return a locale id as specified in the LDML specification"""
@@ -659,8 +668,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="The name within the parent",
+ description=("""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 12009a6..8ecb911 100644
--- a/src/zope/i18n/locales/__init__.py
+++ b/src/zope/i18n/locales/__init__.py
@@ -19,24 +19,33 @@ import os
from datetime import date
from zope.interface import implementer
+
+# Setup the locale directory
+from zope import i18n
+from zope.i18n.format import DateTimeFormat
+from zope.i18n.format import NumberFormat
from zope.i18n.interfaces.locales import ILocale
-from zope.i18n.interfaces.locales import ILocaleDisplayNames, ILocaleDates
-from zope.i18n.interfaces.locales import ILocaleVersion, ILocaleIdentity
-from zope.i18n.interfaces.locales import ILocaleTimeZone, ILocaleCalendar
-from zope.i18n.interfaces.locales import ILocaleCurrency, ILocaleNumbers
-from zope.i18n.interfaces.locales import ILocaleFormat, ILocaleFormatLength
+from zope.i18n.interfaces.locales import ILocaleCalendar
+from zope.i18n.interfaces.locales import ILocaleCurrency
+from zope.i18n.interfaces.locales import ILocaleDates
+from zope.i18n.interfaces.locales import ILocaleDayContext
+from zope.i18n.interfaces.locales import ILocaleDisplayNames
+from zope.i18n.interfaces.locales import ILocaleFormat
+from zope.i18n.interfaces.locales import ILocaleFormatLength
+from zope.i18n.interfaces.locales import ILocaleIdentity
+from zope.i18n.interfaces.locales import ILocaleMonthContext
+from zope.i18n.interfaces.locales import ILocaleNumbers
from zope.i18n.interfaces.locales import ILocaleOrientation
-from zope.i18n.interfaces.locales import ILocaleDayContext, ILocaleMonthContext
-from zope.i18n.format import NumberFormat, DateTimeFormat
-from zope.i18n.locales.inheritance import \
- AttributeInheritance, InheritingDictionary, NoParentException
+from zope.i18n.interfaces.locales import ILocaleTimeZone
+from zope.i18n.interfaces.locales import ILocaleVersion
+from zope.i18n.locales.inheritance import AttributeInheritance
+from zope.i18n.locales.inheritance import InheritingDictionary
+from zope.i18n.locales.inheritance import NoParentException
# LoadLocaleError is not used, but might be imported from here by others.
from zope.i18n.locales.provider import LoadLocaleError # noqa
from zope.i18n.locales.provider import LocaleProvider
-# Setup the locale directory
-from zope import i18n
LOCALEDIR = os.path.join(os.path.dirname(i18n.__file__), "locales", "data")
# Global LocaleProvider. We really just need this single one.
@@ -77,7 +86,7 @@ calendarAliases = {'islamic': ('arabic',),
@implementer(ILocaleIdentity)
-class LocaleIdentity(object):
+class LocaleIdentity:
"""Represents a unique identification of the locale
This class does not have to deal with inheritance.
@@ -116,12 +125,12 @@ class LocaleIdentity(object):
def __repr__(self):
"""See zope.i18n.interfaces.ILocaleIdentity
"""
- return "<LocaleIdentity (%s, %s, %s, %s)>" % (
+ return "<LocaleIdentity ({}, {}, {}, {})>".format(
self.language, self.script, self.territory, self.variant)
@implementer(ILocaleVersion)
-class LocaleVersion(object):
+class LocaleVersion:
"""Represents a particular version of a locale
This class does not have to deal with inheritance.
@@ -190,7 +199,7 @@ class LocaleDisplayNames(AttributeInheritance):
@implementer(ILocaleTimeZone)
-class LocaleTimeZone(object):
+class LocaleTimeZone:
"""Specifies one of the timezones of a specific locale.
The attributes of this class are not inherited, since all timezone
@@ -217,7 +226,7 @@ class LocaleTimeZone(object):
@implementer(ILocaleFormat)
-class LocaleFormat(object):
+class LocaleFormat:
"""Specifies one of the format of a specific format length.
The attributes of this class are not inherited, since all format
@@ -229,8 +238,8 @@ class LocaleFormat(object):
def __init__(self, type=None):
"""Initialize the object."""
self.type = type
- self.displayName = u""
- self.pattern = u""
+ self.displayName = ""
+ self.pattern = ""
@implementer(ILocaleFormatLength)
@@ -250,7 +259,7 @@ class LocaleMonthContext(AttributeInheritance):
def __init__(self, type=None):
"""Initialize the object."""
self.type = type
- self.default = u"wide"
+ self.default = "wide"
@implementer(ILocaleDayContext)
@@ -259,7 +268,7 @@ class LocaleDayContext(AttributeInheritance):
def __init__(self, type=None):
"""Initialize the object."""
self.type = type
- self.default = u"wide"
+ self.default = "wide"
@implementer(ILocaleCalendar)
@@ -498,15 +507,15 @@ class LocaleDates(AttributeInheritance):
"""
def getFormatter(self, category, length=None, name=None,
- calendar=u"gregorian"):
+ calendar="gregorian"):
"""See zope.i18n.interfaces.locales.ILocaleDates"""
- if category not in (u"date", u"time", u"dateTime"):
+ if category not in ("date", "time", "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 ("gregorian", "arabic", "chinese",
+ "civil-arabic", "hebrew", "japanese",
+ "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 ("short", "medium", "long", "full", None):
raise ValueError('Invalid format length: %s' % length)
cal = self.calendars[calendar]
@@ -544,7 +553,7 @@ class LocaleDates(AttributeInheritance):
@implementer(ILocaleCurrency)
-class LocaleCurrency(object):
+class LocaleCurrency:
"""Simple implementation of ILocaleCurrency without inheritance support,
since it is not needed for a single currency."""
@@ -634,8 +643,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 ("decimal", "percent", "scientific", "currency")
+ assert length in ("short", "medium", "long", "full", None)
formats = getattr(self, category + 'Formats')
if length is None:
diff --git a/src/zope/i18n/locales/inheritance.py b/src/zope/i18n/locales/inheritance.py
index e597b78..809b6fe 100644
--- a/src/zope/i18n/locales/inheritance.py
+++ b/src/zope/i18n/locales/inheritance.py
@@ -21,10 +21,11 @@ locale inheritance is not inheritance in the programming sense.
__docformat__ = 'restructuredtext'
from zope.deprecation import deprecate
-
from zope.interface import implementer
-from zope.i18n.interfaces.locales import \
- ILocaleInheritance, IAttributeInheritance, IDictionaryInheritance
+
+from zope.i18n.interfaces.locales import IAttributeInheritance
+from zope.i18n.interfaces.locales import IDictionaryInheritance
+from zope.i18n.interfaces.locales import ILocaleInheritance
class NoParentException(AttributeError):
@@ -32,7 +33,7 @@ class NoParentException(AttributeError):
@implementer(ILocaleInheritance)
-class Inheritance(object):
+class Inheritance:
"""A simple base version of locale inheritance.
This object contains some shared code amongst the various
@@ -109,7 +110,7 @@ class AttributeInheritance(Inheritance):
not name.startswith('__')):
value.__parent__ = self
value.__name__ = name
- super(AttributeInheritance, self).__setattr__(name, value)
+ super().__setattr__(name, value)
def __getattr__(self, name):
"""See zope.i18n.interfaces.locales.ILocaleInheritance"""
@@ -129,7 +130,7 @@ class AttributeInheritance(Inheritance):
# Note that we cannot use the normal setattr function, since
# __setattr__ of this class tries to assign a parent and name,
# which we do not want to override.
- super(AttributeInheritance, self).__setattr__(name, value)
+ super().__setattr__(name, value)
return value
@@ -200,7 +201,7 @@ class InheritingDictionary(Inheritance, dict):
if ILocaleInheritance.providedBy(value):
value.__parent__ = self
value.__name__ = name
- super(InheritingDictionary, self).__setitem__(name, value)
+ super().__setitem__(name, value)
def __getitem__(self, name):
"""See zope.i18n.interfaces.locales.ILocaleInheritance"""
@@ -211,7 +212,7 @@ class InheritingDictionary(Inheritance, dict):
pass
else:
return selfUp.__getitem__(name)
- return super(InheritingDictionary, self).__getitem__(name)
+ return super().__getitem__(name)
def get(self, name, default=None):
"""See zope.i18n.interfaces.locales.ILocaleInheritance"""
diff --git a/src/zope/i18n/locales/provider.py b/src/zope/i18n/locales/provider.py
index 9e7f66b..6396898 100644
--- a/src/zope/i18n/locales/provider.py
+++ b/src/zope/i18n/locales/provider.py
@@ -17,7 +17,9 @@ The Locale Provider looks up locales and loads them from the XML data, if
necessary.
"""
import os
+
from zope.interface import implementer
+
from zope.i18n.interfaces.locales import ILocaleProvider
@@ -26,7 +28,7 @@ class LoadLocaleError(Exception):
@implementer(ILocaleProvider)
-class LocaleProvider(object):
+class LocaleProvider:
"""A locale provider that gets its data from the XML data."""
def __init__(self, locale_dir):
diff --git a/src/zope/i18n/locales/tests/test_docstrings.py b/src/zope/i18n/locales/tests/test_docstrings.py
index faa4e97..59a8f52 100644
--- a/src/zope/i18n/locales/tests/test_docstrings.py
+++ b/src/zope/i18n/locales/tests/test_docstrings.py
@@ -15,9 +15,9 @@
"""
import unittest
from doctest import DocTestSuite
+
from zope.i18n.locales.inheritance import AttributeInheritance
from zope.i18n.locales.inheritance import NoParentException
-
from zope.i18n.testing import unicode_checker
diff --git a/src/zope/i18n/locales/tests/test_fallbackcollator.py b/src/zope/i18n/locales/tests/test_fallbackcollator.py
index ad78b72..f3a2761 100644
--- a/src/zope/i18n/locales/tests/test_fallbackcollator.py
+++ b/src/zope/i18n/locales/tests/test_fallbackcollator.py
@@ -12,8 +12,8 @@
#
##############################################################################
-import unittest
import doctest
+import unittest
from zope.i18n.testing import unicode_checker
diff --git a/src/zope/i18n/locales/tests/test_locales.py b/src/zope/i18n/locales/tests/test_locales.py
index 523b1d2..42968cc 100644
--- a/src/zope/i18n/locales/tests/test_locales.py
+++ b/src/zope/i18n/locales/tests/test_locales.py
@@ -13,19 +13,21 @@
##############################################################################
"""This module tests the LocaleProvider and everything that goes with it.
"""
-import os
import datetime
+import os
from unittest import TestCase
+import zope.i18n
from zope.i18n.interfaces.locales import ILocaleProvider
from zope.i18n.locales import locales
-from zope.i18n.locales.provider import LocaleProvider, LoadLocaleError
+from zope.i18n.locales.provider import LoadLocaleError
+from zope.i18n.locales.provider import LocaleProvider
+
-import zope.i18n
datadir = os.path.join(os.path.dirname(zope.i18n.__file__), 'locales', 'data')
-class AbstractTestILocaleProviderMixin(object):
+class AbstractTestILocaleProviderMixin:
"""Test the functionality of an implmentation of the ILocaleProvider
interface."""
diff --git a/src/zope/i18n/locales/tests/test_xmlfactory.py b/src/zope/i18n/locales/tests/test_xmlfactory.py
index e11097c..e3e82f9 100644
--- a/src/zope/i18n/locales/tests/test_xmlfactory.py
+++ b/src/zope/i18n/locales/tests/test_xmlfactory.py
@@ -14,10 +14,11 @@
"""Testing all XML Locale functionality.
"""
import os
-from unittest import TestCase, TestSuite
+from unittest import TestCase
+from unittest import TestSuite
-from zope.i18n.locales.xmlfactory import LocaleFactory
import zope.i18n
+from zope.i18n.locales.xmlfactory import LocaleFactory
class LocaleXMLFileTestCase(TestCase):
diff --git a/src/zope/i18n/locales/xmlfactory.py b/src/zope/i18n/locales/xmlfactory.py
index f1ed219..c6ac415 100644
--- a/src/zope/i18n/locales/xmlfactory.py
+++ b/src/zope/i18n/locales/xmlfactory.py
@@ -13,18 +13,30 @@
##############################################################################
"""XML Locale-related objects and functions
"""
-from datetime import date, time
+from datetime import date
+from datetime import time
from xml.dom.minidom import parse as parseXML
-from zope.i18n.locales import Locale, LocaleDisplayNames, LocaleDates
-from zope.i18n.locales import LocaleVersion, LocaleIdentity, LocaleTimeZone
-from zope.i18n.locales import LocaleCalendar, LocaleCurrency, LocaleNumbers
-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 import Locale
+from zope.i18n.locales import LocaleCalendar
+from zope.i18n.locales import LocaleCurrency
+from zope.i18n.locales import LocaleDates
+from zope.i18n.locales import LocaleDayContext
+from zope.i18n.locales import LocaleDisplayNames
+from zope.i18n.locales import LocaleFormat
+from zope.i18n.locales import LocaleFormatLength
+from zope.i18n.locales import LocaleIdentity
+from zope.i18n.locales import LocaleMonthContext
+from zope.i18n.locales import LocaleNumbers
+from zope.i18n.locales import LocaleOrientation
+from zope.i18n.locales import LocaleTimeZone
+from zope.i18n.locales import LocaleVersion
+from zope.i18n.locales import calendarAliases
+from zope.i18n.locales import dayMapping
from zope.i18n.locales.inheritance import InheritingDictionary
-class LocaleFactory(object):
+class LocaleFactory:
"""This class creates a Locale object from an ICU XML file."""
def __init__(self, path):
@@ -35,7 +47,7 @@ class LocaleFactory(object):
self._data = parseXML(path).documentElement
def _getText(self, nodelist):
- rc = u''
+ rc = ''
for node in nodelist:
if node.nodeType == node.TEXT_NODE:
rc = rc + node.data
@@ -983,7 +995,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 ("generic", "standard", "daylight"):
# get long name
long_desc = None
if long:
@@ -1066,10 +1078,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 ("decimal", "group", "list", "percentSign",
+ "nativeZeroDigit", "patternDigit", "plusSign",
+ "minusSign", "exponential", "perMille",
+ "infinity", "nan"):
nodes = symbols_nodes[0].getElementsByTagName(name)
if nodes:
symbols[name] = self._getText(nodes[0].childNodes)
@@ -1225,7 +1237,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') == "true"
nodes = curr_node.getElementsByTagName('displayName')
if nodes:
@@ -1298,8 +1310,8 @@ class LocaleFactory(object):
return
delimiters = InheritingDictionary()
- for name in (u'quotationStart', u"quotationEnd",
- u"alternateQuotationStart", u"alternateQuotationEnd"):
+ for name in ('quotationStart', "quotationEnd",
+ "alternateQuotationStart", "alternateQuotationEnd"):
nodes = delimiters_nodes[0].getElementsByTagName(name)
if nodes:
delimiters[name] = self._getText(nodes[0].childNodes)
@@ -1330,7 +1342,7 @@ class LocaleFactory(object):
if not orientation_nodes:
return
orientation = LocaleOrientation()
- for name in (u"characters", u"lines"):
+ for name in ("characters", "lines"):
value = orientation_nodes[0].getAttribute(name)
if value:
setattr(orientation, name, value)
diff --git a/src/zope/i18n/negotiator.py b/src/zope/i18n/negotiator.py
index 3ece221..b790a96 100644
--- a/src/zope/i18n/negotiator.py
+++ b/src/zope/i18n/negotiator.py
@@ -14,6 +14,7 @@
"""Language Negotiator
"""
from zope.interface import implementer
+
from zope.i18n.interfaces import INegotiator
from zope.i18n.interfaces import IUserPreferredLanguages
@@ -35,7 +36,7 @@ def normalize_langs(langs):
@implementer(INegotiator)
-class Negotiator(object):
+class Negotiator:
def getLanguage(self, langs, env):
envadapter = IUserPreferredLanguages(env)
diff --git a/src/zope/i18n/simpletranslationdomain.py b/src/zope/i18n/simpletranslationdomain.py
index b20385a..46e0020 100644
--- a/src/zope/i18n/simpletranslationdomain.py
+++ b/src/zope/i18n/simpletranslationdomain.py
@@ -13,15 +13,16 @@
##############################################################################
"""This is a simple implementation of the ITranslationDomain interface.
"""
-from zope.interface import implementer
from zope.component import getUtility
-from zope.i18n._compat import text_type
-from zope.i18n.interfaces import ITranslationDomain, INegotiator
+from zope.interface import implementer
+
from zope.i18n import interpolate
+from zope.i18n.interfaces import INegotiator
+from zope.i18n.interfaces import ITranslationDomain
@implementer(ITranslationDomain)
-class SimpleTranslationDomain(object):
+class SimpleTranslationDomain:
"""This is the simplest implementation of the ITranslationDomain I
could come up with.
@@ -58,7 +59,7 @@ class SimpleTranslationDomain(object):
# Find a translation; if nothing is found, use the default
# value
if default is None:
- default = text_type(msgid)
+ default = str(msgid)
text = self.messages.get((target_language, msgid))
if text is None:
text = default
diff --git a/src/zope/i18n/testing.py b/src/zope/i18n/testing.py
index 035827c..37b9b51 100644
--- a/src/zope/i18n/testing.py
+++ b/src/zope/i18n/testing.py
@@ -21,6 +21,7 @@ import re
from zope.testing import renormalizing
+
rules = []
if bytes is not str:
rules = [
@@ -38,7 +39,7 @@ def setUp(test=None):
zope.component.provideAdapter(BrowserLanguages)
-class PlacelessSetup(object):
+class PlacelessSetup:
def setUp(self):
"""
diff --git a/src/zope/i18n/testmessagecatalog.py b/src/zope/i18n/testmessagecatalog.py
index b88b3d7..17a0925 100644
--- a/src/zope/i18n/testmessagecatalog.py
+++ b/src/zope/i18n/testmessagecatalog.py
@@ -14,13 +14,13 @@
"""Test message catalog
"""
-from zope import interface
import zope.i18n.interfaces
+from zope import interface
from zope.i18n.translationdomain import TranslationDomain
@interface.implementer(zope.i18n.interfaces.IGlobalMessageCatalog)
-class TestMessageCatalog(object):
+class TestMessageCatalog:
language = 'test'
@@ -30,11 +30,11 @@ class TestMessageCatalog(object):
def queryMessage(self, msgid, default=None):
default = getattr(msgid, 'default', default)
if default is not None and default != msgid:
- msg = u"%s (%s)" % (msgid, default)
+ msg = "{} ({})".format(msgid, default)
else:
msg = msgid
- return u"[[%s][%s]]" % (self.domain, msg)
+ return "[[{}][{}]]".format(self.domain, msg)
getMessage = queryMessage
@@ -46,7 +46,7 @@ class TestMessageCatalog(object):
@interface.implementer(zope.i18n.interfaces.ITranslationDomain)
-def TestMessageFallbackDomain(domain_id=u""):
+def TestMessageFallbackDomain(domain_id=""):
domain = TranslationDomain(domain_id)
domain.addCatalog(TestMessageCatalog(domain_id))
return domain
diff --git a/src/zope/i18n/tests/locale3/en/LC_MESSAGES/zope-i18n2.mo b/src/zope/i18n/tests/locale3/en/LC_MESSAGES/zope-i18n2.mo
new file mode 100644
index 0000000..ecfe91c
--- /dev/null
+++ b/src/zope/i18n/tests/locale3/en/LC_MESSAGES/zope-i18n2.mo
Binary files differ
diff --git a/src/zope/i18n/tests/test.py b/src/zope/i18n/tests/test.py
index 62082c3..07897be 100644
--- a/src/zope/i18n/tests/test.py
+++ b/src/zope/i18n/tests/test.py
@@ -13,10 +13,12 @@
##############################################################################
"""Misc tests
"""
+import doctest
import unittest
-import doctest
-from zope.component.testing import setUp, tearDown
+from zope.component.testing import setUp
+from zope.component.testing import tearDown
+
from zope.i18n.testing import unicode_checker
diff --git a/src/zope/i18n/tests/test_compile.py b/src/zope/i18n/tests/test_compile.py
index d82c3e7..0a20cf9 100644
--- a/src/zope/i18n/tests/test_compile.py
+++ b/src/zope/i18n/tests/test_compile.py
@@ -31,9 +31,9 @@ class TestCompile(unittest.TestCase):
self.assertIsNone(compile.compile_mo_file('no_such_domain', ''))
def test_po_exists_but_invalid(self):
- import tempfile
- import shutil
import os.path
+ import shutil
+ import tempfile
td = tempfile.mkdtemp(suffix=".zopei18n_test_compile")
self.addCleanup(shutil.rmtree, td)
@@ -47,10 +47,10 @@ class TestCompile(unittest.TestCase):
str(self.handler))
def test_po_exists_cannot_write_mo(self):
- import tempfile
- import shutil
import os
import os.path
+ import shutil
+ import tempfile
td = tempfile.mkdtemp(suffix=".zopei18n_test_compile")
self.addCleanup(shutil.rmtree, td)
diff --git a/src/zope/i18n/tests/test_formats.py b/src/zope/i18n/tests/test_formats.py
index a266de6..2f993fd 100644
--- a/src/zope/i18n/tests/test_formats.py
+++ b/src/zope/i18n/tests/test_formats.py
@@ -13,31 +13,33 @@
##############################################################################
"""This module tests the Formats and everything that goes with it.
"""
-import decimal
import datetime
+import decimal
import pickle
from unittest import TestCase
import pytz
-from zope.i18n.interfaces import IDateTimeFormat
from zope.i18n.format import DateTimeFormat
-from zope.i18n.format import parseDateTimePattern, buildDateTimeParseInfo
-from zope.i18n.format import DateTimePatternParseError, DateTimeParseError
-
-from zope.i18n.interfaces import INumberFormat
-from zope.i18n.format import NumberFormat, NumberParseError
-from zope.i18n.format import parseNumberPattern
+from zope.i18n.format import DateTimeParseError
+from zope.i18n.format import DateTimePatternParseError
+from zope.i18n.format import NumberFormat
+from zope.i18n.format import NumberParseError
from zope.i18n.format import NumberPatternParseError
+from zope.i18n.format import buildDateTimeParseInfo
+from zope.i18n.format import parseDateTimePattern
+from zope.i18n.format import parseNumberPattern
+from zope.i18n.interfaces import IDateTimeFormat
+from zope.i18n.interfaces import INumberFormat
-class LocaleStub(object):
+class LocaleStub:
pass
-class LocaleCalendarStub(object):
+class LocaleCalendarStub:
- type = u"gregorian"
+ type = "gregorian"
months = {
1: ('Januar', 'Jan'),
@@ -102,14 +104,7 @@ class LocaleCalendarStub(object):
raise NotImplementedError()
-class _TestCase(TestCase):
- # Avoid deprecation warnings in Python 3 by making the preferred
- # method name available for Python 2.
- assertRaisesRegex = getattr(
- TestCase, 'assertRaisesRegex', TestCase.assertRaisesRegexp)
-
-
-class TestDateTimePatternParser(_TestCase):
+class TestDateTimePatternParser(TestCase):
"""Extensive tests for the ICU-based-syntax datetime pattern parser."""
def testParseSimpleTimePattern(self):
@@ -207,7 +202,7 @@ class TestDateTimePatternParser(_TestCase):
)
-class TestBuildDateTimeParseInfo(_TestCase):
+class TestBuildDateTimeParseInfo(TestCase):
"""This class tests the functionality of the buildDateTimeParseInfo()
method with the German locale.
"""
@@ -250,9 +245,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 = ["Januar", "Februar", "Maerz", "April",
+ "Mai", "Juni", "Juli", "August", "September", "Oktober",
+ "November", "Dezember"]
self.assertEqual(self.info(('M', 4)), '(' + '|'.join(names) + ')')
def testMonthAbbr(self):
@@ -276,7 +271,7 @@ class TestBuildDateTimeParseInfo(_TestCase):
self.assertEqual(self.info(('E', 3)), '(' + '|'.join(names) + ')')
-class TestDateTimeFormat(_TestCase):
+class TestDateTimeFormat(TestCase):
"""Test the functionality of an implmentation of the ILocaleProvider
interface."""
@@ -630,69 +625,69 @@ class TestDateTimeFormat(_TestCase):
def testFormatDayInYear(self):
self.assertEqual(
self.format.format(datetime.date(2003, 1, 3), 'D'),
- u"3")
+ "3")
self.assertEqual(
self.format.format(datetime.date(2003, 1, 3), 'DD'),
- u"03")
+ "03")
self.assertEqual(
self.format.format(datetime.date(2003, 1, 3), 'DDD'),
- u"003")
+ "003")
self.assertEqual(
self.format.format(datetime.date(2003, 12, 31), 'D'),
- u"365")
+ "365")
self.assertEqual(
self.format.format(datetime.date(2003, 12, 31), 'DD'),
- u"365")
+ "365")
self.assertEqual(
self.format.format(datetime.date(2003, 12, 31), 'DDD'),
- u"365")
+ "365")
self.assertEqual(
self.format.format(datetime.date(2004, 12, 31), 'DDD'),
- u"366")
+ "366")
def testFormatDayOfWeekInMOnth(self):
self.assertEqual(
self.format.format(datetime.date(2003, 1, 3), 'F'),
- u"1")
+ "1")
self.assertEqual(
self.format.format(datetime.date(2003, 1, 10), 'F'),
- u"2")
+ "2")
self.assertEqual(
self.format.format(datetime.date(2003, 1, 17), 'F'),
- u"3")
+ "3")
self.assertEqual(
self.format.format(datetime.date(2003, 1, 24), 'F'),
- u"4")
+ "4")
self.assertEqual(
self.format.format(datetime.date(2003, 1, 31), 'F'),
- u"5")
+ "5")
self.assertEqual(
self.format.format(datetime.date(2003, 1, 6), 'F'),
- u"1")
+ "1")
def testFormatUnusualFormats(self):
self.assertEqual(
self.format.format(datetime.date(2003, 1, 3), 'DDD-yyyy'),
- u"003-2003")
+ "003-2003")
self.assertEqual(
self.format.format(datetime.date(2003, 1, 10),
"F. EEEE 'im' MMMM, yyyy"),
- u"2. Freitag im Januar, 2003")
+ "2. Freitag im Januar, 2003")
def testFormatGregorianEra(self):
self.assertEqual(
self.format.format(datetime.date(2017, 12, 17), 'G'),
- u'n. Chr.'
+ 'n. Chr.'
)
def testFormateMonthLengthOne(self):
self.assertEqual(
self.format.format(datetime.date(2017, 12, 17), 'M'),
- u'12'
+ '12'
)
-class TestNumberPatternParser(_TestCase):
+class TestNumberPatternParser(TestCase):
"""Extensive tests for the ICU-based-syntax number pattern parser."""
def testParseSimpleIntegerPattern(self):
@@ -1047,7 +1042,7 @@ class TestNumberPatternParser(_TestCase):
neg_pattern)
-class TestNumberFormat(_TestCase):
+class TestNumberFormat(TestCase):
"""Test the functionality of an implmentation of the NumberFormat."""
format = NumberFormat(symbols={
diff --git a/src/zope/i18n/tests/test_gettextmessagecatalog.py b/src/zope/i18n/tests/test_gettextmessagecatalog.py
index 5bd93df..0272898 100644
--- a/src/zope/i18n/tests/test_gettextmessagecatalog.py
+++ b/src/zope/i18n/tests/test_gettextmessagecatalog.py
@@ -14,6 +14,7 @@
"""Test a gettext implementation of a Message Catalog.
"""
import os
+
from zope.i18n.gettextmessagecatalog import GettextMessageCatalog
from zope.i18n.tests import test_imessagecatalog
diff --git a/src/zope/i18n/tests/test_imessagecatalog.py b/src/zope/i18n/tests/test_imessagecatalog.py
index 36fb43c..95295cd 100644
--- a/src/zope/i18n/tests/test_imessagecatalog.py
+++ b/src/zope/i18n/tests/test_imessagecatalog.py
@@ -14,10 +14,12 @@
"""This is an 'abstract' test for the IMessageCatalog interface.
"""
import unittest
+
from zope.interface.verify import verifyObject
-from zope.i18n.interfaces import IMessageCatalog
from zope.schema import getValidationErrors
+from zope.i18n.interfaces import IMessageCatalog
+
class TestIMessageCatalog(unittest.TestCase):
diff --git a/src/zope/i18n/tests/test_itranslationdomain.py b/src/zope/i18n/tests/test_itranslationdomain.py
index bea5360..81bec8a 100644
--- a/src/zope/i18n/tests/test_itranslationdomain.py
+++ b/src/zope/i18n/tests/test_itranslationdomain.py
@@ -14,22 +14,21 @@
"""This is an 'abstract' test for the ITranslationDomain interface.
"""
import unittest
-from zope.interface.verify import verifyObject
-from zope.interface import implementer
import zope.component
from zope.component.testing import PlacelessSetup
-
+from zope.interface import implementer
+from zope.interface.verify import verifyObject
from zope.schema import getValidationErrors
-from zope.i18n._compat import text_type
-from zope.i18n.negotiator import negotiator
-from zope.i18n.interfaces import INegotiator, IUserPreferredLanguages
+from zope.i18n.interfaces import INegotiator
from zope.i18n.interfaces import ITranslationDomain
+from zope.i18n.interfaces import IUserPreferredLanguages
+from zope.i18n.negotiator import negotiator
@implementer(IUserPreferredLanguages)
-class Environment(object):
+class Environment:
def __init__(self, langs=()):
self.langs = langs
@@ -45,7 +44,7 @@ class TestITranslationDomain(PlacelessSetup):
raise NotImplementedError()
def setUp(self):
- super(TestITranslationDomain, self).setUp()
+ super().setUp()
self._domain = self._getTranslationDomain()
# Setup the negotiator utility
@@ -94,7 +93,7 @@ class TestITranslationDomain(PlacelessSetup):
translate = self._domain.translate
translated = translate('no way', target_language='en')
self.assertEqual(translated, "no way")
- self.assertIsInstance(translated, text_type)
+ self.assertIsInstance(translated, str)
def testNoTargetLanguage(self):
translate = self._domain.translate
diff --git a/src/zope/i18n/tests/test_negotiator.py b/src/zope/i18n/tests/test_negotiator.py
index 9267332..bf5ba4d 100644
--- a/src/zope/i18n/tests/test_negotiator.py
+++ b/src/zope/i18n/tests/test_negotiator.py
@@ -15,14 +15,15 @@
"""
import unittest
-from zope.i18n.negotiator import Negotiator
-from zope.i18n.interfaces import IUserPreferredLanguages
from zope.component.testing import PlacelessSetup
from zope.interface import implementer
+from zope.i18n.interfaces import IUserPreferredLanguages
+from zope.i18n.negotiator import Negotiator
+
@implementer(IUserPreferredLanguages)
-class Env(object):
+class Env:
def __init__(self, langs=()):
self.langs = langs
@@ -34,7 +35,7 @@ class Env(object):
class NegotiatorTest(PlacelessSetup, unittest.TestCase):
def setUp(self):
- super(NegotiatorTest, self).setUp()
+ super().setUp()
self.negotiator = Negotiator()
def test_findLanguages(self):
@@ -55,5 +56,5 @@ class NegotiatorTest(PlacelessSetup, unittest.TestCase):
def test_suite():
return unittest.TestSuite((
- unittest.makeSuite(NegotiatorTest),
+ unittest.defaultTestLoader.loadTestsFromTestCase(NegotiatorTest),
))
diff --git a/src/zope/i18n/tests/test_plurals.py b/src/zope/i18n/tests/test_plurals.py
index bc97bf3..2577bed 100644
--- a/src/zope/i18n/tests/test_plurals.py
+++ b/src/zope/i18n/tests/test_plurals.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Foundation and Contributors.
@@ -18,24 +17,26 @@ import os
import unittest
import zope.component
-from zope.i18n import tests, translate
-from zope.i18n.translationdomain import TranslationDomain
-from zope.i18n.gettextmessagecatalog import GettextMessageCatalog
from zope.i18nmessageid import MessageFactory
+
+from zope.i18n import tests
+from zope.i18n import translate
+from zope.i18n.gettextmessagecatalog import GettextMessageCatalog
from zope.i18n.interfaces import ITranslationDomain
+from zope.i18n.translationdomain import TranslationDomain
class TestPlurals(unittest.TestCase):
def _getMessageCatalog(self, locale, variant="default"):
path = os.path.dirname(tests.__file__)
- self._path = os.path.join(path, '%s-%s.mo' % (locale, variant))
+ self._path = os.path.join(path, '{}-{}.mo'.format(locale, variant))
catalog = GettextMessageCatalog(locale, variant, self._path)
return catalog
def _getTranslationDomain(self, locale, variant="default"):
path = os.path.dirname(tests.__file__)
- self._path = os.path.join(path, '%s-%s.mo' % (locale, variant))
+ self._path = os.path.join(path, '{}-{}.mo'.format(locale, variant))
catalog = GettextMessageCatalog(locale, variant, self._path)
domain = TranslationDomain('default')
domain.addCatalog(catalog)
@@ -124,22 +125,22 @@ class TestPlurals(unittest.TestCase):
self.assertEqual(catalog.getPluralMessage(
'There is one file.', 'There are %d files.', 0),
- u"Istnieją 0 plików.")
+ "Istnieją 0 plików.")
self.assertEqual(catalog.getPluralMessage(
'There is one file.', 'There are %d files.', 1),
- u"Istnieje 1 plik.")
+ "Istnieje 1 plik.")
self.assertEqual(catalog.getPluralMessage(
'There is one file.', 'There are %d files.', 3),
- u"Istnieją 3 pliki.")
+ "Istnieją 3 pliki.")
self.assertEqual(catalog.getPluralMessage(
'There is one file.', 'There are %d files.', 17),
- u"Istnieją 17 plików.")
+ "Istnieją 17 plików.")
self.assertEqual(catalog.getPluralMessage(
'There is one file.', 'There are %d files.', 23),
- u"Istnieją 23 pliki.")
+ "Istnieją 23 pliki.")
self.assertEqual(catalog.getPluralMessage(
'There is one file.', 'There are %d files.', 28),
- u"Istnieją 28 plików.")
+ "Istnieją 28 plików.")
def test_floater(self):
"""Test with the number being a float.
diff --git a/src/zope/i18n/tests/test_simpletranslationdomain.py b/src/zope/i18n/tests/test_simpletranslationdomain.py
index 2f233d6..4c88d8e 100644
--- a/src/zope/i18n/tests/test_simpletranslationdomain.py
+++ b/src/zope/i18n/tests/test_simpletranslationdomain.py
@@ -14,6 +14,7 @@
"""This module tests the regular persistent Translation Domain.
"""
import unittest
+
from zope.i18n.simpletranslationdomain import SimpleTranslationDomain
from zope.i18n.tests.test_itranslationdomain import TestITranslationDomain
@@ -22,7 +23,8 @@ data = {
('en', 'short_greeting'): 'Hello!',
('de', 'short_greeting'): 'Hallo!',
('en', 'greeting'): 'Hello $name, how are you?',
- ('de', 'greeting'): 'Hallo $name, wie geht es Dir?'}
+ ('de', 'greeting'): 'Hallo $name, wie geht es Dir?',
+}
class TestSimpleTranslationDomain(unittest.TestCase, TestITranslationDomain):
@@ -36,9 +38,3 @@ class TestSimpleTranslationDomain(unittest.TestCase, TestITranslationDomain):
def _getTranslationDomain(self):
domain = SimpleTranslationDomain('default', data)
return domain
-
-
-def test_suite():
- suite = unittest.TestSuite()
- suite.addTest(unittest.makeSuite(TestSimpleTranslationDomain))
- return suite
diff --git a/src/zope/i18n/tests/test_testmessagecatalog.py b/src/zope/i18n/tests/test_testmessagecatalog.py
index e5c8e57..a28148a 100644
--- a/src/zope/i18n/tests/test_testmessagecatalog.py
+++ b/src/zope/i18n/tests/test_testmessagecatalog.py
@@ -12,11 +12,11 @@
#
##############################################################################
-import unittest
import doctest
+import unittest
def test_suite():
- return unittest.TestSuite((
+ return unittest.TestSuite(
doctest.DocFileSuite('../testmessagecatalog.rst')
- ))
+ )
diff --git a/src/zope/i18n/tests/test_translationdomain.py b/src/zope/i18n/tests/test_translationdomain.py
index 5d55156..b681dc4 100644
--- a/src/zope/i18n/tests/test_translationdomain.py
+++ b/src/zope/i18n/tests/test_translationdomain.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2001-2008 Zope Foundation and Contributors.
@@ -14,16 +13,18 @@
##############################################################################
"""This module tests the regular persistent Translation Domain.
"""
-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
+import unittest
+
+import zope.component
from zope.i18nmessageid import MessageFactory
+
+from zope.i18n.gettextmessagecatalog import GettextMessageCatalog
from zope.i18n.interfaces import ITranslationDomain
+from zope.i18n.tests.test_itranslationdomain import Environment
+from zope.i18n.tests.test_itranslationdomain import TestITranslationDomain
+from zope.i18n.translationdomain import TranslationDomain
-import zope.component
testdir = os.path.dirname(__file__)
@@ -68,19 +69,19 @@ class TestGlobalTranslationDomain(TestITranslationDomain, unittest.TestCase):
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("", target_language='en'), "")
+ self.assertEqual(translate("", target_language='foo'), "")
def testStringTranslate(self):
self.assertEqual(
- self._domain.translate(u"short_greeting", target_language='en'),
- u"Hello!")
+ self._domain.translate("short_greeting", target_language='en'),
+ "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("short_greeting", 'default')
+ self.assertEqual(translate(msgid, target_language='en'), "Hello!")
# MessageID attributes override arguments
msgid = factory('43-not-there', 'this ${that} the other',
mapping={'that': 'THAT'})
@@ -91,13 +92,13 @@ class TestGlobalTranslationDomain(TestITranslationDomain, unittest.TestCase):
def testMessageIDRecursiveTranslate(self):
factory = MessageFactory('default')
translate = self._domain.translate
- msgid_sub1 = factory(u"44-not-there", '${blue}',
+ msgid_sub1 = factory("44-not-there", '${blue}',
mapping={'blue': 'BLUE'})
- msgid_sub2 = factory(u"45-not-there", '${yellow}',
+ msgid_sub2 = factory("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("46-not-there", 'Color: ${color1}/${color2}',
mapping=mapping)
self.assertEqual(
translate(msgid, target_language='en', default="default"),
@@ -106,9 +107,9 @@ class TestGlobalTranslationDomain(TestITranslationDomain, unittest.TestCase):
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',
+ msgid1 = factory("47-not-there", 'Message 1 and $msg2',
mapping={})
- msgid2 = factory(u"48-not-there", 'Message 2 and $msg1',
+ msgid2 = factory("48-not-there", 'Message 2 and $msg1',
mapping={})
msgid1.mapping['msg2'] = msgid2
msgid2.mapping['msg1'] = msgid1
@@ -118,7 +119,7 @@ class TestGlobalTranslationDomain(TestITranslationDomain, unittest.TestCase):
# message id but a Unicode with a directly passed mapping
self.assertEqual(
"Color: BLUE/YELLOW",
- translate(u"Color: ${color1}/${color2}", mapping=mapping,
+ translate("Color: ${color1}/${color2}", mapping=mapping,
target_language='en'))
# If we have mapping with a message id from a different
@@ -126,9 +127,9 @@ class TestGlobalTranslationDomain(TestITranslationDomain, unittest.TestCase):
# message domain is not registered yet, we should return a
# default translation.
alt_factory = MessageFactory('alt')
- msgid_sub = alt_factory(u"special", default=u"oohhh")
+ msgid_sub = alt_factory("special", default="oohhh")
mapping = {'message': msgid_sub}
- msgid = factory(u"46-not-there", 'Message: ${message}',
+ msgid = factory("46-not-there", 'Message: ${message}',
mapping=mapping)
# test we get a default with no domain registered
self.assertEqual(
@@ -156,9 +157,9 @@ class TestGlobalTranslationDomain(TestITranslationDomain, unittest.TestCase):
zope.component.provideUtility(domain, ITranslationDomain, 'alt')
factory = MessageFactory('alt')
- msgid = factory(u"special", 'default')
+ msgid = factory("special", 'default')
self.assertEqual(
- self._domain.translate(msgid, target_language='en'), u"Wow")
+ self._domain.translate(msgid, target_language='en'), "Wow")
def testSimpleFallbackTranslation(self):
translate = self._domain.translate
@@ -166,11 +167,11 @@ class TestGlobalTranslationDomain(TestITranslationDomain, unittest.TestCase):
# 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!")
+ "Hello!")
# Same test, but use the context argument instead of target_language
context = Environment()
eq(translate('short_greeting', context=context),
- u"Hello!")
+ "Hello!")
def testInterpolationWithoutTranslation(self):
translate = self._domain.translate
@@ -233,7 +234,7 @@ class TestGlobalTranslationDomain(TestITranslationDomain, unittest.TestCase):
domain.addCatalog(standard_catalog)
self.assertEqual(
domain.translate('short_greeting', target_language='sr'),
- u"Hello in Serbian Standard!",
+ "Hello in Serbian Standard!",
)
# Test the Latin file.
@@ -241,12 +242,12 @@ class TestGlobalTranslationDomain(TestITranslationDomain, unittest.TestCase):
domain.addCatalog(latin_catalog)
self.assertEqual(
domain.translate('short_greeting', target_language='sr'),
- u"Hello in Serbian Latin!",
+ "Hello in Serbian Latin!",
)
# Note that sr@Latn is not recognizes as language id.
self.assertEqual(
domain.translate('short_greeting', target_language='sr@Latn'),
- u"short_greeting",
+ "short_greeting",
)
# Test the Cyrillic file.
@@ -254,7 +255,7 @@ class TestGlobalTranslationDomain(TestITranslationDomain, unittest.TestCase):
domain.addCatalog(cyrillic_catalog)
self.assertEqual(
domain.translate('short_greeting', target_language='sr'),
- u"Hello in српски!",
+ "Hello in српски!",
)
# When I have all three locales, this is the order that
@@ -266,5 +267,5 @@ class TestGlobalTranslationDomain(TestITranslationDomain, unittest.TestCase):
# The Latin one is first, so it wins.
self.assertEqual(
domain.translate('short_greeting', target_language='sr'),
- u"Hello in Serbian Latin!",
+ "Hello in Serbian Latin!",
)
diff --git a/src/zope/i18n/tests/test_zcml.py b/src/zope/i18n/tests/test_zcml.py
index cd3d2b4..5540beb 100644
--- a/src/zope/i18n/tests/test_zcml.py
+++ b/src/zope/i18n/tests/test_zcml.py
@@ -25,9 +25,8 @@ from zope.component.testing import PlacelessSetup
from zope.configuration import xmlconfig
import zope.i18n.tests
-from zope.i18n._compat import text_type
-from zope.i18n.interfaces import ITranslationDomain
from zope.i18n import config
+from zope.i18n.interfaces import ITranslationDomain
template = """\
@@ -43,13 +42,13 @@ class DirectivesTest(PlacelessSetup, unittest.TestCase):
# This test suite needs the [zcml] and [compile] extra dependencies
def setUp(self):
- super(DirectivesTest, self).setUp()
+ super().setUp()
self.context = xmlconfig.file('meta.zcml', zope.i18n)
self.allowed = config.ALLOWED_LANGUAGES
config.ALLOWED_LANGUAGES = None
def tearDown(self):
- super(DirectivesTest, self).tearDown()
+ super().tearDown()
config.ALLOWED_LANGUAGES = self.allowed
def testRegisterTranslations(self):
@@ -64,7 +63,7 @@ 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'), [text_type(path)])
+ self.assertEqual(util._catalogs.get('en'), [str(path)])
def testAllowedTranslations(self):
self.assertTrue(queryUtility(ITranslationDomain) is None)
@@ -79,7 +78,7 @@ class DirectivesTest(PlacelessSetup, unittest.TestCase):
'locale', 'de', 'LC_MESSAGES', 'zope-i18n.mo')
util = getUtility(ITranslationDomain, 'zope-i18n')
self.assertEqual(util._catalogs,
- {'test': ['test'], 'de': [text_type(path)]})
+ {'test': ['test'], 'de': [str(path)]})
def testRegisterDistributedTranslations(self):
self.assertTrue(queryUtility(ITranslationDomain, 'zope-i18n') is None)
@@ -102,16 +101,16 @@ class DirectivesTest(PlacelessSetup, unittest.TestCase):
util = getUtility(ITranslationDomain, 'zope-i18n')
self.assertEqual(util._catalogs.get('test'), ['test', 'test'])
self.assertEqual(util._catalogs.get('en'),
- [text_type(path1), text_type(path2)])
+ [str(path1), str(path2)])
- msg = util.translate(u"Additional message", target_language='en')
- self.assertEqual(msg, u"Additional message translated")
+ msg = util.translate("Additional message", target_language='en')
+ self.assertEqual(msg, "Additional message translated")
- msg = util.translate(u"New Domain", target_language='en')
- self.assertEqual(msg, u"New Domain translated")
+ msg = util.translate("New Domain", target_language='en')
+ self.assertEqual(msg, "New Domain translated")
- msg = util.translate(u"New Language", target_language='en')
- self.assertEqual(msg, u"New Language translated")
+ msg = util.translate("New Language", target_language='en')
+ self.assertEqual(msg, "New Language translated")
def testRegisterAndCompileTranslations(self):
config.COMPILE_MO_FILES = True
@@ -139,14 +138,14 @@ class DirectivesTest(PlacelessSetup, unittest.TestCase):
''', self.context)
util = getUtility(ITranslationDomain, 'zope-i18n')
self.assertEqual(util._catalogs,
- {'test': ['test'], 'en': [text_type(path)]})
+ {'test': ['test'], 'en': [str(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("I'm a newer file", target_language='en')
+ self.assertEqual(msg, "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("I'm a new file", target_language='en')
+ self.assertEqual(msg, "I'm a new file translated")
# Reset the mtime of the mo file
os.utime(path, (path_atime, path_mtime))
@@ -165,7 +164,7 @@ class DirectivesTest(PlacelessSetup, unittest.TestCase):
'locale3', 'en', 'LC_MESSAGES', 'zope-i18n.mo')
util = getUtility(ITranslationDomain, 'zope-i18n')
self.assertEqual(util._catalogs,
- {'test': ['test'], 'en': [text_type(path)]})
+ {'test': ['test'], 'en': [str(path)]})
self.assertTrue(queryUtility(ITranslationDomain, 'zope-i18n2') is None)
diff --git a/src/zope/i18n/tests/testi18nawareobject.py b/src/zope/i18n/tests/testi18nawareobject.py
index 996416b..bc71044 100644
--- a/src/zope/i18n/tests/testi18nawareobject.py
+++ b/src/zope/i18n/tests/testi18nawareobject.py
@@ -15,12 +15,13 @@
"""
import unittest
-from zope.i18n.interfaces import II18nAware
from zope.interface import implementer
+from zope.i18n.interfaces import II18nAware
+
@implementer(II18nAware)
-class I18nAwareContentObject(object):
+class I18nAwareContentObject:
def __init__(self):
self.content = {}
@@ -55,7 +56,7 @@ class I18nAwareContentObject(object):
############################################################
-class AbstractTestII18nAwareMixin(object):
+class AbstractTestII18nAwareMixin:
def setUp(self):
self.object = self._createObject()
diff --git a/src/zope/i18n/translationdomain.py b/src/zope/i18n/translationdomain.py
index e56d75c..6c587b3 100644
--- a/src/zope/i18n/translationdomain.py
+++ b/src/zope/i18n/translationdomain.py
@@ -16,11 +16,12 @@
import zope.component
import zope.interface
-
from zope.i18nmessageid import Message
-from zope.i18n import translate, interpolate
-from zope.i18n._compat import text_type
-from zope.i18n.interfaces import ITranslationDomain, INegotiator
+
+from zope.i18n import interpolate
+from zope.i18n import translate
+from zope.i18n.interfaces import INegotiator
+from zope.i18n.interfaces import ITranslationDomain
# The configuration should specify a list of fallback languages for the
@@ -35,7 +36,7 @@ LANGUAGE_FALLBACKS = ['en']
@zope.interface.implementer(ITranslationDomain)
-class TranslationDomain(object):
+class TranslationDomain:
def __init__(self, domain, fallbacks=None):
self.domain = (
@@ -74,8 +75,8 @@ class TranslationDomain(object):
"""See zope.i18n.interfaces.ITranslationDomain"""
# if the msgid is empty, let's save a lot of calculations and return
# an empty string.
- if msgid == u'':
- return u''
+ if msgid == '':
+ return ''
if target_language is None and context is not None:
langs = self._catalogs.keys()
@@ -124,9 +125,9 @@ class TranslationDomain(object):
msgid_plural, default_plural, number, seen)
if default is None:
- default = text_type(msgid)
+ default = str(msgid)
if msgid_plural is not None and default_plural is None:
- default_plural = text_type(msgid_plural)
+ default_plural = str(msgid_plural)
# 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 caeff9b..acce5fa 100644
--- a/src/zope/i18n/zcml.py
+++ b/src/zope/i18n/zcml.py
@@ -1,4 +1,3 @@
-
# ##############################################################################
#
# Copyright (c) 2001, 2002 Zope Foundation and Contributors.
@@ -16,8 +15,8 @@
"""
__docformat__ = 'restructuredtext'
-import os
import logging
+import os
from glob import glob
from zope.component import getSiteManager
@@ -30,9 +29,9 @@ from zope.schema import TextLine
from zope.i18n import config
from zope.i18n.compile import compile_mo_file
from zope.i18n.gettextmessagecatalog import GettextMessageCatalog
+from zope.i18n.interfaces import ITranslationDomain
from zope.i18n.testmessagecatalog import TestMessageCatalog
from zope.i18n.translationdomain import TranslationDomain
-from zope.i18n.interfaces import ITranslationDomain
logger = logging.getLogger("zope.i18n")
@@ -42,15 +41,15 @@ class IRegisterTranslationsDirective(Interface):
"""Register translations with the global site manager."""
directory = Path(
- title=u"Directory",
- description=u"Directory containing the translations",
+ title="Directory",
+ description="Directory containing the translations",
required=True
)
domain = TextLine(
- title=u"Domain",
- description=(u"Translation domain to register. If not specified, "
- u"all domains found in the directory are registered"),
+ title="Domain",
+ description=("Translation domain to register. If not specified, "
+ "all domains found in the directory are registered"),
required=False
)
diff --git a/tox.ini b/tox.ini
index 7cf2afc..04de302 100644
--- a/tox.ini
+++ b/tox.ini
@@ -4,14 +4,11 @@
minversion = 3.18
envlist =
lint
- py27
- py35
- py36
py37
py38
py39
py310
- pypy
+ py311
pypy3
docs
coverage
@@ -21,7 +18,7 @@ usedevelop = true
deps =
commands =
zope-testrunner --test-path=src {posargs:-vc}
- !py27-!pypy: sphinx-build -b doctest -d {envdir}/.cache/doctrees docs {envdir}/.cache/doctest
+ sphinx-build -b doctest -d {envdir}/.cache/doctrees docs {envdir}/.cache/doctest
extras =
test
docs
@@ -29,15 +26,26 @@ extras =
[testenv:lint]
basepython = python3
skip_install = true
+commands =
+ isort --check-only --diff {toxinidir}/src {toxinidir}/setup.py
+ flake8 src setup.py
+ check-manifest
+ check-python-versions
deps =
- flake8
check-manifest
check-python-versions >= 0.19.1
wheel
+ flake8
+ isort
+
+[testenv:isort-apply]
+basepython = python3
+skip_install = true
+commands_pre =
+deps =
+ isort
commands =
- flake8 src setup.py
- check-manifest
- check-python-versions
+ isort {toxinidir}/src {toxinidir}/setup.py []
[testenv:docs]
basepython = python3
@@ -53,17 +61,15 @@ allowlist_externals =
mkdir
deps =
coverage
- coverage-python-version
commands =
mkdir -p {toxinidir}/parts/htmlcov
coverage run -m zope.testrunner --test-path=src {posargs:-vc}
coverage run -a -m sphinx -b doctest -d {envdir}/.cache/doctrees docs {envdir}/.cache/doctest
- coverage html
- coverage report -m --fail-under=99
+ coverage html --ignore-errors
+ coverage report --ignore-errors --show-missing --fail-under=99
[coverage:run]
branch = True
-plugins = coverage_python_version
source = zope.i18n
[coverage:report]