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:
Doug Hellmann 2014-10-09 15:30:41 -04:00
parent 53635eae0f
commit ba05e9a9b9
35 changed files with 507 additions and 201 deletions

View File

@ -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:

View File

@ -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::

View File

@ -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::

View File

@ -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()

View File

@ -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

View File

@ -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
View 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 *

View File

@ -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)

View File

@ -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',

View File

@ -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

View File

@ -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.')

View File

@ -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
View 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
View 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)

View File

View 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):

View 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')

View File

@ -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

View 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())

View File

@ -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):

View File

@ -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,

View File

@ -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):

View File

@ -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__)

View 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')

View File

@ -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):

View File

@ -22,7 +22,7 @@ classifier =
[files]
packages =
oslo
oslo.i18n
oslo_i18n
namespace_packages =
oslo

View File

@ -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):

View File

@ -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__)

View File

@ -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
View 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))

View File

@ -38,4 +38,4 @@ exclude=.venv,.git,.tox,dist,doc,*openstack/common*,*lib/python*,*egg,build,__in
[hacking]
import_exceptions =
oslo.i18n._i18n._
oslo_i18n._i18n._