Move out of the oslo namespace package
Move the public API out of oslo.i18n to oslo_i18n. Retain the ability to import from the old namespace package for backwards compatibility for this release cycle. bp/drop-namespace-packages Change-Id: I800f121c271d8e69f6e776c4aef509bbb8008170
This commit is contained in:
parent
53635eae0f
commit
ba05e9a9b9
@ -2,12 +2,12 @@
|
||||
API
|
||||
=====
|
||||
|
||||
oslo.i18n
|
||||
oslo_i18n
|
||||
=========
|
||||
|
||||
.. automodule:: oslo.i18n
|
||||
.. automodule:: oslo_i18n
|
||||
|
||||
.. autoclass:: oslo.i18n.TranslatorFactory
|
||||
.. autoclass:: oslo_i18n.TranslatorFactory
|
||||
:members:
|
||||
|
||||
.. seealso::
|
||||
@ -15,24 +15,24 @@ oslo.i18n
|
||||
An example of using a :class:`TranslatorFactory` is provided in
|
||||
:ref:`integration-module`.
|
||||
|
||||
.. autofunction:: oslo.i18n.enable_lazy
|
||||
.. autofunction:: oslo_i18n.enable_lazy
|
||||
|
||||
.. seealso::
|
||||
|
||||
:ref:`lazy-translation`
|
||||
|
||||
.. autofunction:: oslo.i18n.translate
|
||||
.. autofunction:: oslo_i18n.translate
|
||||
|
||||
.. autofunction:: oslo.i18n.get_available_languages
|
||||
.. autofunction:: oslo_i18n.get_available_languages
|
||||
|
||||
oslo.i18n.log
|
||||
oslo_i18n.log
|
||||
=============
|
||||
|
||||
.. automodule:: oslo.i18n.log
|
||||
.. automodule:: oslo_i18n.log
|
||||
:members:
|
||||
|
||||
oslo.i18n.fixture
|
||||
oslo_i18n.fixture
|
||||
=================
|
||||
|
||||
.. automodule:: oslo.i18n.fixture
|
||||
.. automodule:: oslo_i18n.fixture
|
||||
:members:
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
Text messages the user sees via exceptions or API calls should be
|
||||
translated using
|
||||
:py:attr:`TranslatorFactory.primary <oslo.i18n.TranslatorFactory.primary>`, which should
|
||||
:py:attr:`TranslatorFactory.primary <oslo_i18n.TranslatorFactory.primary>`, which should
|
||||
be installed as ``_()`` in the integration module.
|
||||
|
||||
.. seealso::
|
||||
|
@ -16,16 +16,16 @@ Creating an Integration Module
|
||||
|
||||
To use oslo.i18n in a project, you will need to create a small
|
||||
integration module to hold an instance of
|
||||
:class:`~oslo.i18n.TranslatorFactory` and references to
|
||||
:class:`~oslo_i18n.TranslatorFactory` and references to
|
||||
the marker functions the factory creates.
|
||||
|
||||
::
|
||||
|
||||
# app/i18n.py
|
||||
|
||||
from oslo import i18n
|
||||
import oslo_i18n
|
||||
|
||||
_translators = i18n.TranslatorFactory(domain='myapp')
|
||||
_translators = oslo_i18n.TranslatorFactory(domain='myapp')
|
||||
|
||||
# The primary translation function using the well-known name "_"
|
||||
_ = _translators.primary
|
||||
@ -151,14 +151,14 @@ To enable lazy translation, call :func:`enable_lazy`.
|
||||
|
||||
::
|
||||
|
||||
from oslo import i18n
|
||||
import oslo_i18n
|
||||
|
||||
i18n.enable_lazy()
|
||||
oslo_i18n.enable_lazy()
|
||||
|
||||
Translating Messages
|
||||
====================
|
||||
|
||||
Use :func:`~oslo.i18n.translate` to translate strings to
|
||||
Use :func:`~oslo_i18n.translate` to translate strings to
|
||||
a specific locale. :func:`translate` handles delayed translation and
|
||||
strings that have already been translated immediately. It should be
|
||||
used at the point where the locale to be used is known, which is often
|
||||
@ -167,9 +167,9 @@ emitted.
|
||||
|
||||
::
|
||||
|
||||
from oslo import i18n
|
||||
import oslo_i18n
|
||||
|
||||
trans_msg = i18n.translate(msg, desired_locale=my_locale)
|
||||
trans_msg = oslo_i18n.translate(msg, desired_locale=my_locale)
|
||||
|
||||
if desired_locale is not specified then the default locale is used.
|
||||
|
||||
@ -178,14 +178,14 @@ Available Languages
|
||||
|
||||
Only the languages that have translations provided are available for
|
||||
translation. To determine which languages are available the
|
||||
:func:`~oslo.i18n.get_available_languages` is provided. Since different languages
|
||||
:func:`~oslo_i18n.get_available_languages` is provided. Since different languages
|
||||
can be installed for each domain, the domain must be specified.
|
||||
|
||||
::
|
||||
|
||||
from oslo import i18n
|
||||
import oslo_i18n
|
||||
|
||||
avail_lang = i18n.get_available_languages('myapp')
|
||||
avail_lang = oslo_i18n.get_available_languages('myapp')
|
||||
|
||||
.. seealso::
|
||||
|
||||
|
@ -10,7 +10,22 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from ._factory import *
|
||||
from ._gettextutils import *
|
||||
from ._lazy import *
|
||||
from ._translate import *
|
||||
import warnings
|
||||
|
||||
from oslo_i18n._factory import *
|
||||
from oslo_i18n._gettextutils import *
|
||||
from oslo_i18n._lazy import *
|
||||
from oslo_i18n._translate import *
|
||||
|
||||
|
||||
def deprecated():
|
||||
new_name = __name__.replace('.', '_')
|
||||
warnings.warn(
|
||||
('The oslo namespace package is deprecated. Please use %s instead.' %
|
||||
new_name),
|
||||
DeprecationWarning,
|
||||
stacklevel=3,
|
||||
)
|
||||
|
||||
|
||||
deprecated()
|
||||
|
@ -9,57 +9,5 @@
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
"""Test fixtures for working with oslo.i18n.
|
||||
|
||||
"""
|
||||
|
||||
import fixtures
|
||||
import six
|
||||
|
||||
from oslo.i18n import _message
|
||||
|
||||
|
||||
class Translation(fixtures.Fixture):
|
||||
"""Fixture for managing translatable strings.
|
||||
|
||||
This class provides methods for creating translatable strings
|
||||
using both lazy translation and immediate translation. It can be
|
||||
used to generate the different types of messages returned from
|
||||
oslo.i18n to test code that may need to know about the type to
|
||||
handle them differently (for example, error handling in WSGI apps,
|
||||
or logging).
|
||||
|
||||
Use this class to generate messages instead of toggling the global
|
||||
lazy flag and using the regular translation factory.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, domain='test-domain'):
|
||||
"""Initialize the fixture.
|
||||
|
||||
:param domain: The translation domain. This is not expected to
|
||||
coincide with an actual set of message
|
||||
catalogs, but it can.
|
||||
:type domain: str
|
||||
"""
|
||||
self.domain = domain
|
||||
|
||||
def lazy(self, msg):
|
||||
"""Return a lazily translated message.
|
||||
|
||||
:param msg: Input message string. May optionally include
|
||||
positional or named string interpolation markers.
|
||||
:type msg: str or unicode
|
||||
|
||||
"""
|
||||
return _message.Message(msg, domain=self.domain)
|
||||
|
||||
def immediate(self, msg):
|
||||
"""Return a string as though it had been translated immediately.
|
||||
|
||||
:param msg: Input message string. May optionally include
|
||||
positional or named string interpolation markers.
|
||||
:type msg: str or unicode
|
||||
|
||||
"""
|
||||
return six.text_type(msg)
|
||||
from oslo_i18n.fixture import * # noqa
|
||||
|
@ -1,7 +1,3 @@
|
||||
# Copyright 2012 Red Hat, Inc.
|
||||
# Copyright 2013 IBM Corp.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
@ -14,84 +10,4 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
"""logging utilities for translation
|
||||
"""
|
||||
|
||||
from logging import handlers
|
||||
|
||||
from oslo.i18n import _translate
|
||||
|
||||
|
||||
class TranslationHandler(handlers.MemoryHandler):
|
||||
"""Handler that translates records before logging them.
|
||||
|
||||
When lazy translation is enabled in the application (see
|
||||
:func:`~oslo.i18n.enable_lazy`), the :class:`TranslationHandler`
|
||||
uses its locale configuration setting to determine how to
|
||||
translate LogRecord objects before forwarding them to the
|
||||
logging.Handler.
|
||||
|
||||
When lazy translation is disabled, the message in the LogRecord is
|
||||
converted to unicode without any changes and then forwarded to the
|
||||
logging.Handler.
|
||||
|
||||
The handler can be configured declaratively in the
|
||||
``logging.conf`` as follows::
|
||||
|
||||
[handlers]
|
||||
keys = translatedlog, translator
|
||||
|
||||
[handler_translatedlog]
|
||||
class = handlers.WatchedFileHandler
|
||||
args = ('/var/log/api-localized.log',)
|
||||
formatter = context
|
||||
|
||||
[handler_translator]
|
||||
class = oslo.i18n.log.TranslationHandler
|
||||
target = translatedlog
|
||||
args = ('zh_CN',)
|
||||
|
||||
If the specified locale is not available in the system, the handler will
|
||||
log in the default locale.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, locale=None, target=None):
|
||||
"""Initialize a TranslationHandler
|
||||
|
||||
:param locale: locale to use for translating messages
|
||||
:param target: logging.Handler object to forward
|
||||
LogRecord objects to after translation
|
||||
"""
|
||||
# NOTE(luisg): In order to allow this handler to be a wrapper for
|
||||
# other handlers, such as a FileHandler, and still be able to
|
||||
# configure it using logging.conf, this handler has to extend
|
||||
# MemoryHandler because only the MemoryHandlers' logging.conf
|
||||
# parsing is implemented such that it accepts a target handler.
|
||||
handlers.MemoryHandler.__init__(self, capacity=0, target=target)
|
||||
self.locale = locale
|
||||
|
||||
def setFormatter(self, fmt):
|
||||
self.target.setFormatter(fmt)
|
||||
|
||||
def emit(self, record):
|
||||
# We save the message from the original record to restore it
|
||||
# after translation, so other handlers are not affected by this
|
||||
original_msg = record.msg
|
||||
original_args = record.args
|
||||
|
||||
try:
|
||||
self._translate_and_log_record(record)
|
||||
finally:
|
||||
record.msg = original_msg
|
||||
record.args = original_args
|
||||
|
||||
def _translate_and_log_record(self, record):
|
||||
record.msg = _translate.translate(record.msg, self.locale)
|
||||
|
||||
# In addition to translating the message, we also need to translate
|
||||
# arguments that were passed to the log method that were not part
|
||||
# of the main message e.g., log.info(_('Some message %s'), this_one))
|
||||
record.args = _translate.translate_args(record.args, self.locale)
|
||||
|
||||
self.target.emit(record)
|
||||
from oslo_i18n.log import * # noqa
|
||||
|
16
oslo_i18n/__init__.py
Normal file
16
oslo_i18n/__init__.py
Normal file
@ -0,0 +1,16 @@
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from ._factory import *
|
||||
from ._gettextutils import *
|
||||
from ._lazy import *
|
||||
from ._translate import *
|
@ -21,9 +21,9 @@ import os
|
||||
|
||||
import six
|
||||
|
||||
from oslo.i18n import _lazy
|
||||
from oslo.i18n import _locale
|
||||
from oslo.i18n import _message
|
||||
from oslo_i18n import _lazy
|
||||
from oslo_i18n import _locale
|
||||
from oslo_i18n import _message
|
||||
|
||||
|
||||
__all__ = [
|
||||
@ -75,7 +75,7 @@ class TranslatorFactory(object):
|
||||
m = t.gettext if six.PY3 else t.ugettext
|
||||
|
||||
def f(msg):
|
||||
"""oslo.i18n.gettextutils translation function."""
|
||||
"""oslo_i18n.gettextutils translation function."""
|
||||
if _lazy.USE_LAZY:
|
||||
return _message.Message(msg, domain=domain)
|
||||
return m(msg)
|
@ -24,8 +24,8 @@ import os
|
||||
from babel import localedata
|
||||
import six
|
||||
|
||||
from oslo.i18n import _factory
|
||||
from oslo.i18n import _locale
|
||||
from oslo_i18n import _factory
|
||||
from oslo_i18n import _locale
|
||||
|
||||
__all__ = [
|
||||
'install',
|
@ -16,10 +16,10 @@
|
||||
"""Translation support for messages in this library.
|
||||
"""
|
||||
|
||||
from oslo.i18n import _factory
|
||||
from oslo_i18n import _factory
|
||||
|
||||
# Create the global translation functions.
|
||||
_translators = _factory.TranslatorFactory('oslo.i18n')
|
||||
_translators = _factory.TranslatorFactory('oslo_i18n')
|
||||
|
||||
# The primary translation function using the well-known name "_"
|
||||
_ = _translators.primary
|
@ -23,8 +23,8 @@ import os
|
||||
|
||||
import six
|
||||
|
||||
from oslo.i18n import _locale
|
||||
from oslo.i18n import _translate
|
||||
from oslo_i18n import _locale
|
||||
from oslo_i18n import _translate
|
||||
|
||||
|
||||
class Message(six.text_type):
|
||||
@ -149,7 +149,7 @@ class Message(six.text_type):
|
||||
return six.text_type(param)
|
||||
|
||||
def __add__(self, other):
|
||||
from oslo.i18n._i18n import _
|
||||
from oslo_i18n._i18n import _
|
||||
msg = _('Message objects do not support addition.')
|
||||
raise TypeError(msg)
|
||||
|
||||
@ -160,7 +160,7 @@ class Message(six.text_type):
|
||||
def __str__(self):
|
||||
# NOTE(luisg): Logging in python 2.6 tries to str() log records,
|
||||
# and it expects specifically a UnicodeError in order to proceed.
|
||||
from oslo.i18n._i18n import _
|
||||
from oslo_i18n._i18n import _
|
||||
msg = _('Message objects do not support str() because they may '
|
||||
'contain non-ascii characters. '
|
||||
'Please use unicode() or translate() instead.')
|
@ -36,7 +36,7 @@ def translate(obj, desired_locale=None):
|
||||
it could not be translated
|
||||
|
||||
"""
|
||||
from oslo.i18n import _message # avoid circular dependency at module level
|
||||
from oslo_i18n import _message # avoid circular dependency at module level
|
||||
message = obj
|
||||
if not isinstance(message, _message.Message):
|
||||
# If the object to translate is not already translatable,
|
65
oslo_i18n/fixture.py
Normal file
65
oslo_i18n/fixture.py
Normal file
@ -0,0 +1,65 @@
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
"""Test fixtures for working with oslo_i18n.
|
||||
|
||||
"""
|
||||
|
||||
import fixtures
|
||||
import six
|
||||
|
||||
from oslo_i18n import _message
|
||||
|
||||
|
||||
class Translation(fixtures.Fixture):
|
||||
"""Fixture for managing translatable strings.
|
||||
|
||||
This class provides methods for creating translatable strings
|
||||
using both lazy translation and immediate translation. It can be
|
||||
used to generate the different types of messages returned from
|
||||
oslo_i18n to test code that may need to know about the type to
|
||||
handle them differently (for example, error handling in WSGI apps,
|
||||
or logging).
|
||||
|
||||
Use this class to generate messages instead of toggling the global
|
||||
lazy flag and using the regular translation factory.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, domain='test-domain'):
|
||||
"""Initialize the fixture.
|
||||
|
||||
:param domain: The translation domain. This is not expected to
|
||||
coincide with an actual set of message
|
||||
catalogs, but it can.
|
||||
:type domain: str
|
||||
"""
|
||||
self.domain = domain
|
||||
|
||||
def lazy(self, msg):
|
||||
"""Return a lazily translated message.
|
||||
|
||||
:param msg: Input message string. May optionally include
|
||||
positional or named string interpolation markers.
|
||||
:type msg: str or unicode
|
||||
|
||||
"""
|
||||
return _message.Message(msg, domain=self.domain)
|
||||
|
||||
def immediate(self, msg):
|
||||
"""Return a string as though it had been translated immediately.
|
||||
|
||||
:param msg: Input message string. May optionally include
|
||||
positional or named string interpolation markers.
|
||||
:type msg: str or unicode
|
||||
|
||||
"""
|
||||
return six.text_type(msg)
|
97
oslo_i18n/log.py
Normal file
97
oslo_i18n/log.py
Normal file
@ -0,0 +1,97 @@
|
||||
# Copyright 2012 Red Hat, Inc.
|
||||
# Copyright 2013 IBM Corp.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
"""logging utilities for translation
|
||||
"""
|
||||
|
||||
from logging import handlers
|
||||
|
||||
from oslo_i18n import _translate
|
||||
|
||||
|
||||
class TranslationHandler(handlers.MemoryHandler):
|
||||
"""Handler that translates records before logging them.
|
||||
|
||||
When lazy translation is enabled in the application (see
|
||||
:func:`~oslo_i18n.enable_lazy`), the :class:`TranslationHandler`
|
||||
uses its locale configuration setting to determine how to
|
||||
translate LogRecord objects before forwarding them to the
|
||||
logging.Handler.
|
||||
|
||||
When lazy translation is disabled, the message in the LogRecord is
|
||||
converted to unicode without any changes and then forwarded to the
|
||||
logging.Handler.
|
||||
|
||||
The handler can be configured declaratively in the
|
||||
``logging.conf`` as follows::
|
||||
|
||||
[handlers]
|
||||
keys = translatedlog, translator
|
||||
|
||||
[handler_translatedlog]
|
||||
class = handlers.WatchedFileHandler
|
||||
args = ('/var/log/api-localized.log',)
|
||||
formatter = context
|
||||
|
||||
[handler_translator]
|
||||
class = oslo_i18n.log.TranslationHandler
|
||||
target = translatedlog
|
||||
args = ('zh_CN',)
|
||||
|
||||
If the specified locale is not available in the system, the handler will
|
||||
log in the default locale.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, locale=None, target=None):
|
||||
"""Initialize a TranslationHandler
|
||||
|
||||
:param locale: locale to use for translating messages
|
||||
:param target: logging.Handler object to forward
|
||||
LogRecord objects to after translation
|
||||
"""
|
||||
# NOTE(luisg): In order to allow this handler to be a wrapper for
|
||||
# other handlers, such as a FileHandler, and still be able to
|
||||
# configure it using logging.conf, this handler has to extend
|
||||
# MemoryHandler because only the MemoryHandlers' logging.conf
|
||||
# parsing is implemented such that it accepts a target handler.
|
||||
handlers.MemoryHandler.__init__(self, capacity=0, target=target)
|
||||
self.locale = locale
|
||||
|
||||
def setFormatter(self, fmt):
|
||||
self.target.setFormatter(fmt)
|
||||
|
||||
def emit(self, record):
|
||||
# We save the message from the original record to restore it
|
||||
# after translation, so other handlers are not affected by this
|
||||
original_msg = record.msg
|
||||
original_args = record.args
|
||||
|
||||
try:
|
||||
self._translate_and_log_record(record)
|
||||
finally:
|
||||
record.msg = original_msg
|
||||
record.args = original_args
|
||||
|
||||
def _translate_and_log_record(self, record):
|
||||
record.msg = _translate.translate(record.msg, self.locale)
|
||||
|
||||
# In addition to translating the message, we also need to translate
|
||||
# arguments that were passed to the log method that were not part
|
||||
# of the main message e.g., log.info(_('Some message %s'), this_one))
|
||||
record.args = _translate.translate_args(record.args, self.locale)
|
||||
|
||||
self.target.emit(record)
|
0
oslo_i18n/tests/__init__.py
Normal file
0
oslo_i18n/tests/__init__.py
Normal file
@ -18,9 +18,9 @@ import mock
|
||||
from oslotest import base as test_base
|
||||
import six
|
||||
|
||||
from oslo.i18n import _factory
|
||||
from oslo.i18n import _lazy
|
||||
from oslo.i18n import _message
|
||||
from oslo_i18n import _factory
|
||||
from oslo_i18n import _lazy
|
||||
from oslo_i18n import _message
|
||||
|
||||
|
||||
class TranslatorFactoryTest(test_base.BaseTestCase):
|
38
oslo_i18n/tests/test_fixture.py
Normal file
38
oslo_i18n/tests/test_fixture.py
Normal file
@ -0,0 +1,38 @@
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from oslotest import base as test_base
|
||||
import six
|
||||
|
||||
from oslo_i18n import _message
|
||||
from oslo_i18n import fixture
|
||||
|
||||
|
||||
class FixtureTest(test_base.BaseTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(FixtureTest, self).setUp()
|
||||
self.trans_fixture = self.useFixture(fixture.Translation())
|
||||
|
||||
def test_lazy(self):
|
||||
msg = self.trans_fixture.lazy('this is a lazy message')
|
||||
self.assertIsInstance(msg, _message.Message)
|
||||
self.assertEqual(msg.msgid, 'this is a lazy message')
|
||||
|
||||
def test_immediate(self):
|
||||
msg = self.trans_fixture.immediate('this is a lazy message')
|
||||
# Python 2.6 does not have assertNotIsInstance
|
||||
self.assertFalse(isinstance(msg, _message.Message))
|
||||
self.assertIsInstance(msg, six.text_type)
|
||||
self.assertEqual(msg, u'this is a lazy message')
|
@ -23,10 +23,10 @@ from oslotest import base as test_base
|
||||
from oslotest import moxstubout
|
||||
import six
|
||||
|
||||
from oslo.i18n import _factory
|
||||
from oslo.i18n import _gettextutils
|
||||
from oslo.i18n import _lazy
|
||||
from oslo.i18n import _message
|
||||
from oslo_i18n import _factory
|
||||
from oslo_i18n import _gettextutils
|
||||
from oslo_i18n import _lazy
|
||||
from oslo_i18n import _message
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
@ -41,7 +41,7 @@ class GettextTest(test_base.BaseTestCase):
|
||||
self.mox = moxfixture.mox
|
||||
# remember so we can reset to it later in case it changes
|
||||
self._USE_LAZY = _lazy.USE_LAZY
|
||||
self.t = _factory.TranslatorFactory('oslo.i18n.test')
|
||||
self.t = _factory.TranslatorFactory('oslo_i18n.test')
|
||||
|
||||
def tearDown(self):
|
||||
# reset to value before test
|
106
oslo_i18n/tests/test_handler.py
Normal file
106
oslo_i18n/tests/test_handler.py
Normal file
@ -0,0 +1,106 @@
|
||||
# Copyright 2012 Red Hat, Inc.
|
||||
# Copyright 2013 IBM Corp.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import logging
|
||||
|
||||
import mock
|
||||
from oslotest import base as test_base
|
||||
import six
|
||||
|
||||
from oslo_i18n import _message
|
||||
from oslo_i18n import log as i18n_log
|
||||
from oslo_i18n.tests import fakes
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class TranslationHandlerTestCase(test_base.BaseTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TranslationHandlerTestCase, self).setUp()
|
||||
|
||||
self.stream = six.StringIO()
|
||||
self.destination_handler = logging.StreamHandler(self.stream)
|
||||
self.translation_handler = i18n_log.TranslationHandler('zh_CN')
|
||||
self.translation_handler.setTarget(self.destination_handler)
|
||||
|
||||
self.logger = logging.getLogger('localehander_logger')
|
||||
self.logger.setLevel(logging.DEBUG)
|
||||
self.logger.addHandler(self.translation_handler)
|
||||
|
||||
def test_set_formatter(self):
|
||||
formatter = 'some formatter'
|
||||
self.translation_handler.setFormatter(formatter)
|
||||
self.assertEqual(formatter, self.translation_handler.target.formatter)
|
||||
|
||||
@mock.patch('gettext.translation')
|
||||
def test_emit_translated_message(self, mock_translation):
|
||||
log_message = 'A message to be logged'
|
||||
log_message_translation = 'A message to be logged in Chinese'
|
||||
translations = {log_message: log_message_translation}
|
||||
translations_map = {'zh_CN': translations}
|
||||
translator = fakes.FakeTranslations.translator(translations_map)
|
||||
mock_translation.side_effect = translator
|
||||
|
||||
msg = _message.Message(log_message)
|
||||
|
||||
self.logger.info(msg)
|
||||
self.assertIn(log_message_translation, self.stream.getvalue())
|
||||
|
||||
@mock.patch('gettext.translation')
|
||||
def test_emit_translated_message_with_args(self, mock_translation):
|
||||
log_message = 'A message to be logged %s'
|
||||
log_message_translation = 'A message to be logged in Chinese %s'
|
||||
log_arg = 'Arg to be logged'
|
||||
log_arg_translation = 'An arg to be logged in Chinese'
|
||||
|
||||
translations = {log_message: log_message_translation,
|
||||
log_arg: log_arg_translation}
|
||||
translations_map = {'zh_CN': translations}
|
||||
translator = fakes.FakeTranslations.translator(translations_map)
|
||||
mock_translation.side_effect = translator
|
||||
|
||||
msg = _message.Message(log_message)
|
||||
arg = _message.Message(log_arg)
|
||||
|
||||
self.logger.info(msg, arg)
|
||||
self.assertIn(log_message_translation % log_arg_translation,
|
||||
self.stream.getvalue())
|
||||
|
||||
@mock.patch('gettext.translation')
|
||||
def test_emit_translated_message_with_named_args(self, mock_translation):
|
||||
log_message = 'A message to be logged %(arg1)s $(arg2)s'
|
||||
log_message_translation = 'Chinese msg to be logged %(arg1)s $(arg2)s'
|
||||
log_arg_1 = 'Arg1 to be logged'
|
||||
log_arg_1_translation = 'Arg1 to be logged in Chinese'
|
||||
log_arg_2 = 'Arg2 to be logged'
|
||||
log_arg_2_translation = 'Arg2 to be logged in Chinese'
|
||||
|
||||
translations = {log_message: log_message_translation,
|
||||
log_arg_1: log_arg_1_translation,
|
||||
log_arg_2: log_arg_2_translation}
|
||||
translations_map = {'zh_CN': translations}
|
||||
translator = fakes.FakeTranslations.translator(translations_map)
|
||||
mock_translation.side_effect = translator
|
||||
|
||||
msg = _message.Message(log_message)
|
||||
arg_1 = _message.Message(log_arg_1)
|
||||
arg_2 = _message.Message(log_arg_2)
|
||||
|
||||
self.logger.info(msg, {'arg1': arg_1, 'arg2': arg_2})
|
||||
translation = log_message_translation % {'arg1': log_arg_1_translation,
|
||||
'arg2': log_arg_2_translation}
|
||||
self.assertIn(translation, self.stream.getvalue())
|
@ -16,7 +16,7 @@
|
||||
|
||||
from oslotest import base as test_base
|
||||
|
||||
from oslo.i18n import _lazy
|
||||
from oslo_i18n import _lazy
|
||||
|
||||
|
||||
class LazyTest(test_base.BaseTestCase):
|
@ -15,7 +15,7 @@
|
||||
from oslotest import base as test_base
|
||||
import testscenarios.testcase
|
||||
|
||||
from oslo.i18n import _locale
|
||||
from oslo_i18n import _locale
|
||||
|
||||
|
||||
class LocaleDirVariableTest(testscenarios.testcase.WithScenarios,
|
@ -17,7 +17,7 @@
|
||||
import mock
|
||||
from oslotest import base as test_base
|
||||
|
||||
from oslo.i18n import _factory
|
||||
from oslo_i18n import _factory
|
||||
|
||||
|
||||
class LogLevelTranslationsTest(test_base.BaseTestCase):
|
@ -23,9 +23,9 @@ from oslotest import base as test_base
|
||||
import six
|
||||
import testtools
|
||||
|
||||
from oslo.i18n import _message
|
||||
from tests import fakes
|
||||
from tests import utils
|
||||
from oslo_i18n import _message
|
||||
from oslo_i18n.tests import fakes
|
||||
from oslo_i18n.tests import utils
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
44
oslo_i18n/tests/test_public_api.py
Normal file
44
oslo_i18n/tests/test_public_api.py
Normal file
@ -0,0 +1,44 @@
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
"""A few tests that use the public API to ensure the imports work.
|
||||
"""
|
||||
|
||||
import unittest
|
||||
|
||||
import mock
|
||||
|
||||
import oslo_i18n
|
||||
from oslo_i18n import _lazy
|
||||
|
||||
|
||||
class PublicAPITest(unittest.TestCase):
|
||||
|
||||
def test_create_factory(self):
|
||||
oslo_i18n.TranslatorFactory('domain')
|
||||
|
||||
def test_install(self):
|
||||
with mock.patch('six.moves.builtins'):
|
||||
oslo_i18n.install('domain')
|
||||
|
||||
def test_get_available_languages(self):
|
||||
oslo_i18n.get_available_languages('domains')
|
||||
|
||||
def test_toggle_lazy(self):
|
||||
original = _lazy.USE_LAZY
|
||||
try:
|
||||
oslo_i18n.enable_lazy(True)
|
||||
oslo_i18n.enable_lazy(False)
|
||||
finally:
|
||||
oslo_i18n.enable_lazy(original)
|
||||
|
||||
def test_translate(self):
|
||||
oslo_i18n.translate(u'string')
|
@ -19,10 +19,10 @@ from __future__ import unicode_literals
|
||||
import mock
|
||||
from oslotest import base as test_base
|
||||
|
||||
from oslo.i18n import _message
|
||||
from oslo.i18n import _translate
|
||||
from tests import fakes
|
||||
from tests import utils
|
||||
from oslo_i18n import _message
|
||||
from oslo_i18n import _translate
|
||||
from oslo_i18n.tests import fakes
|
||||
from oslo_i18n.tests import utils
|
||||
|
||||
|
||||
class TranslateTest(test_base.BaseTestCase):
|
@ -22,7 +22,7 @@ classifier =
|
||||
[files]
|
||||
packages =
|
||||
oslo
|
||||
oslo.i18n
|
||||
oslo_i18n
|
||||
namespace_packages =
|
||||
oslo
|
||||
|
||||
|
@ -15,8 +15,8 @@
|
||||
from oslotest import base as test_base
|
||||
import six
|
||||
|
||||
from oslo.i18n import _message
|
||||
from oslo.i18n import fixture
|
||||
from oslo_i18n import _message
|
||||
|
||||
|
||||
class FixtureTest(test_base.BaseTestCase):
|
||||
|
@ -20,9 +20,9 @@ import mock
|
||||
from oslotest import base as test_base
|
||||
import six
|
||||
|
||||
from oslo.i18n import _message
|
||||
from oslo.i18n import log as i18n_log
|
||||
from tests import fakes
|
||||
from oslo_i18n import _message
|
||||
from oslo_i18n.tests import fakes
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
@ -17,7 +17,7 @@ import unittest
|
||||
import mock
|
||||
|
||||
from oslo import i18n
|
||||
from oslo.i18n import _lazy
|
||||
from oslo_i18n import _lazy
|
||||
|
||||
|
||||
class PublicAPITest(unittest.TestCase):
|
||||
|
61
tests/test_warning.py
Normal file
61
tests/test_warning.py
Normal file
@ -0,0 +1,61 @@
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import imp
|
||||
import os
|
||||
import warnings
|
||||
|
||||
import mock
|
||||
from oslotest import base as test_base
|
||||
import six
|
||||
|
||||
|
||||
class DeprecationWarningTest(test_base.BaseTestCase):
|
||||
|
||||
@mock.patch('warnings.warn')
|
||||
def test_warning(self, mock_warn):
|
||||
import oslo.i18n
|
||||
imp.reload(oslo.i18n)
|
||||
self.assertTrue(mock_warn.called)
|
||||
args = mock_warn.call_args
|
||||
self.assertIn('oslo_i18n', args[0][0])
|
||||
self.assertIn('deprecated', args[0][0])
|
||||
self.assertTrue(issubclass(args[0][1], DeprecationWarning))
|
||||
|
||||
def test_real_warning(self):
|
||||
with warnings.catch_warnings(record=True) as warning_msgs:
|
||||
warnings.resetwarnings()
|
||||
warnings.simplefilter('always', DeprecationWarning)
|
||||
import oslo.i18n
|
||||
|
||||
# Use a separate function to get the stack level correct
|
||||
# so we know the message points back to this file. This
|
||||
# corresponds to an import or reload, which isn't working
|
||||
# inside the test under Python 3.3. That may be due to a
|
||||
# difference in the import implementation not triggering
|
||||
# warnings properly when the module is reloaded, or
|
||||
# because the warnings module is mostly implemented in C
|
||||
# and something isn't cleanly resetting the global state
|
||||
# used to track whether a warning needs to be
|
||||
# emitted. Whatever the cause, we definitely see the
|
||||
# warnings.warn() being invoked on a reload (see the test
|
||||
# above) and warnings are reported on the console when we
|
||||
# run the tests. A simpler test script run outside of
|
||||
# testr does correctly report the warnings.
|
||||
def foo():
|
||||
oslo.i18n.deprecated()
|
||||
|
||||
foo()
|
||||
self.assertEqual(1, len(warning_msgs))
|
||||
msg = warning_msgs[0]
|
||||
self.assertIn('oslo_i18n', six.text_type(msg.message))
|
||||
self.assertEqual('test_warning.py', os.path.basename(msg.filename))
|
Loading…
Reference in New Issue
Block a user