Remove oslo.log code and clean up versionutils API

Remove the modules and tests that have moved to oslo.log. Replace the
use of oslo.log with the standard library logging module.

Replace calls to LOG.deprecated() with a new function in versionutils
that is copied from the body of the old implementation.

Add fatal_deprecations configuration option to versionutils, where it is
used now instead of the old log module.

Change-Id: I5903f9a9c521789cbf3381d9741a8a5308767e2d
Closes-Bug: #1373120
Blueprint: fix-import-cycle-log-and-versionutils
This commit is contained in:
Doug Hellmann 2014-09-24 17:57:58 -04:00 committed by Davanum Srinivas (dims)
parent 5ae762c3a0
commit bbf48f00cd
2 changed files with 93 additions and 39 deletions

View File

@ -19,15 +19,24 @@ Helpers for comparing version strings.
import functools import functools
import inspect import inspect
import logging
from oslo.config import cfg
import pkg_resources import pkg_resources
import six import six
from openstack.common._i18n import _ from openstack.common._i18n import _
from openstack.common import log as logging
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
CONF = cfg.CONF
opts = [
cfg.BoolOpt('fatal_deprecations',
default=False,
help='Enables or disables fatal status of deprecations.'),
]
class deprecated(object): class deprecated(object):
@ -127,7 +136,7 @@ class deprecated(object):
@six.wraps(func_or_cls) @six.wraps(func_or_cls)
def wrapped(*args, **kwargs): def wrapped(*args, **kwargs):
LOG.deprecated(msg, details) report_deprecated_feature(LOG, msg, details)
return func_or_cls(*args, **kwargs) return func_or_cls(*args, **kwargs)
return wrapped return wrapped
elif inspect.isclass(func_or_cls): elif inspect.isclass(func_or_cls):
@ -139,7 +148,7 @@ class deprecated(object):
# and added to the oslo-incubator requrements # and added to the oslo-incubator requrements
@functools.wraps(orig_init, assigned=('__name__', '__doc__')) @functools.wraps(orig_init, assigned=('__name__', '__doc__'))
def new_init(self, *args, **kwargs): def new_init(self, *args, **kwargs):
LOG.deprecated(msg, details) report_deprecated_feature(LOG, msg, details)
orig_init(self, *args, **kwargs) orig_init(self, *args, **kwargs)
func_or_cls.__init__ = new_init func_or_cls.__init__ = new_init
return func_or_cls return func_or_cls
@ -201,3 +210,44 @@ def is_compatible(requested_version, current_version, same_major=True):
return False return False
return current_parts >= requested_parts return current_parts >= requested_parts
# Track the messages we have sent already. See
# report_deprecated_feature().
_deprecated_messages_sent = {}
def report_deprecated_feature(logger, msg, *args, **kwargs):
"""Call this function when a deprecated feature is used.
If the system is configured for fatal deprecations then the message
is logged at the 'critical' level and :class:`DeprecatedConfig` will
be raised.
Otherwise, the message will be logged (once) at the 'warn' level.
:raises: :class:`DeprecatedConfig` if the system is configured for
fatal deprecations.
"""
stdmsg = _("Deprecated: %s") % msg
CONF.register_opts(opts)
if CONF.fatal_deprecations:
logger.critical(stdmsg, *args, **kwargs)
raise DeprecatedConfig(msg=stdmsg)
# Using a list because a tuple with dict can't be stored in a set.
sent_args = _deprecated_messages_sent.setdefault(msg, list())
if args in sent_args:
# Already logged this message, so don't log it again.
return
sent_args.append(args)
logger.warn(stdmsg, *args, **kwargs)
class DeprecatedConfig(Exception):
message = _("Fatal call to deprecated config: %(msg)s")
def __init__(self, msg):
super(Exception, self).__init__(self.message % dict(msg=msg))

View File

@ -21,7 +21,7 @@ from openstack.common import versionutils
class DeprecatedTestCase(test_base.BaseTestCase): class DeprecatedTestCase(test_base.BaseTestCase):
def assert_deprecated(self, mock_log, no_removal=False, def assert_deprecated(self, mock_reporter, no_removal=False,
**expected_details): **expected_details):
decorator = versionutils.deprecated decorator = versionutils.deprecated
if 'in_favor_of' in expected_details: if 'in_favor_of' in expected_details:
@ -38,10 +38,14 @@ class DeprecatedTestCase(test_base.BaseTestCase):
expected_msg = getattr( expected_msg = getattr(
decorator, decorator,
'_deprecated_msg_with_no_alternative_no_removal') '_deprecated_msg_with_no_alternative_no_removal')
mock_log.deprecated.assert_called_with(expected_msg, expected_details) # The first argument is the logger, and we don't care about
# that, so ignore it with ANY.
mock_reporter.assert_called_with(mock.ANY,
expected_msg,
expected_details)
@mock.patch('openstack.common.versionutils.LOG', mock.Mock()) @mock.patch('openstack.common.versionutils.report_deprecated_feature')
def test_deprecating_a_function_returns_correct_value(self): def test_deprecating_a_function_returns_correct_value(self, mock_reporter):
@versionutils.deprecated(as_of=versionutils.deprecated.ICEHOUSE) @versionutils.deprecated(as_of=versionutils.deprecated.ICEHOUSE)
def do_outdated_stuff(data): def do_outdated_stuff(data):
@ -52,8 +56,8 @@ class DeprecatedTestCase(test_base.BaseTestCase):
self.assertThat(retval, matchers.Equals(expected_rv)) self.assertThat(retval, matchers.Equals(expected_rv))
@mock.patch('openstack.common.versionutils.LOG', mock.Mock()) @mock.patch('openstack.common.versionutils.report_deprecated_feature')
def test_deprecating_a_method_returns_correct_value(self): def test_deprecating_a_method_returns_correct_value(self, mock_reporter):
class C(object): class C(object):
@versionutils.deprecated(as_of=versionutils.deprecated.ICEHOUSE) @versionutils.deprecated(as_of=versionutils.deprecated.ICEHOUSE)
@ -64,8 +68,8 @@ class DeprecatedTestCase(test_base.BaseTestCase):
self.assertThat(retval, matchers.Equals((1, 'of anything'))) self.assertThat(retval, matchers.Equals((1, 'of anything')))
@mock.patch('openstack.common.versionutils.LOG') @mock.patch('openstack.common.versionutils.report_deprecated_feature')
def test_deprecated_with_unknown_future_release(self, mock_log): def test_deprecated_with_unknown_future_release(self, mock_reporter):
@versionutils.deprecated(as_of=versionutils.deprecated.BEXAR, @versionutils.deprecated(as_of=versionutils.deprecated.BEXAR,
in_favor_of='different_stuff()') in_favor_of='different_stuff()')
@ -74,14 +78,14 @@ class DeprecatedTestCase(test_base.BaseTestCase):
do_outdated_stuff() do_outdated_stuff()
self.assert_deprecated(mock_log, self.assert_deprecated(mock_reporter,
what='do_outdated_stuff()', what='do_outdated_stuff()',
in_favor_of='different_stuff()', in_favor_of='different_stuff()',
as_of='Bexar', as_of='Bexar',
remove_in='D') remove_in='D')
@mock.patch('openstack.common.versionutils.LOG') @mock.patch('openstack.common.versionutils.report_deprecated_feature')
def test_deprecated_with_known_future_release(self, mock_log): def test_deprecated_with_known_future_release(self, mock_reporter):
@versionutils.deprecated(as_of=versionutils.deprecated.GRIZZLY, @versionutils.deprecated(as_of=versionutils.deprecated.GRIZZLY,
in_favor_of='different_stuff()') in_favor_of='different_stuff()')
@ -90,14 +94,14 @@ class DeprecatedTestCase(test_base.BaseTestCase):
do_outdated_stuff() do_outdated_stuff()
self.assert_deprecated(mock_log, self.assert_deprecated(mock_reporter,
what='do_outdated_stuff()', what='do_outdated_stuff()',
in_favor_of='different_stuff()', in_favor_of='different_stuff()',
as_of='Grizzly', as_of='Grizzly',
remove_in='Icehouse') remove_in='Icehouse')
@mock.patch('openstack.common.versionutils.LOG') @mock.patch('openstack.common.versionutils.report_deprecated_feature')
def test_deprecated_without_replacement(self, mock_log): def test_deprecated_without_replacement(self, mock_reporter):
@versionutils.deprecated(as_of=versionutils.deprecated.GRIZZLY) @versionutils.deprecated(as_of=versionutils.deprecated.GRIZZLY)
def do_outdated_stuff(): def do_outdated_stuff():
@ -105,13 +109,13 @@ class DeprecatedTestCase(test_base.BaseTestCase):
do_outdated_stuff() do_outdated_stuff()
self.assert_deprecated(mock_log, self.assert_deprecated(mock_reporter,
what='do_outdated_stuff()', what='do_outdated_stuff()',
as_of='Grizzly', as_of='Grizzly',
remove_in='Icehouse') remove_in='Icehouse')
@mock.patch('openstack.common.versionutils.LOG') @mock.patch('openstack.common.versionutils.report_deprecated_feature')
def test_deprecated_with_custom_what(self, mock_log): def test_deprecated_with_custom_what(self, mock_reporter):
@versionutils.deprecated(as_of=versionutils.deprecated.GRIZZLY, @versionutils.deprecated(as_of=versionutils.deprecated.GRIZZLY,
what='v2.0 API', what='v2.0 API',
@ -121,14 +125,14 @@ class DeprecatedTestCase(test_base.BaseTestCase):
do_outdated_stuff() do_outdated_stuff()
self.assert_deprecated(mock_log, self.assert_deprecated(mock_reporter,
what='v2.0 API', what='v2.0 API',
in_favor_of='v3 API', in_favor_of='v3 API',
as_of='Grizzly', as_of='Grizzly',
remove_in='Icehouse') remove_in='Icehouse')
@mock.patch('openstack.common.versionutils.LOG') @mock.patch('openstack.common.versionutils.report_deprecated_feature')
def test_deprecated_with_removed_next_release(self, mock_log): def test_deprecated_with_removed_next_release(self, mock_reporter):
@versionutils.deprecated(as_of=versionutils.deprecated.GRIZZLY, @versionutils.deprecated(as_of=versionutils.deprecated.GRIZZLY,
remove_in=1) remove_in=1)
@ -137,13 +141,13 @@ class DeprecatedTestCase(test_base.BaseTestCase):
do_outdated_stuff() do_outdated_stuff()
self.assert_deprecated(mock_log, self.assert_deprecated(mock_reporter,
what='do_outdated_stuff()', what='do_outdated_stuff()',
as_of='Grizzly', as_of='Grizzly',
remove_in='Havana') remove_in='Havana')
@mock.patch('openstack.common.versionutils.LOG') @mock.patch('openstack.common.versionutils.report_deprecated_feature')
def test_deprecated_with_removed_plus_3(self, mock_log): def test_deprecated_with_removed_plus_3(self, mock_reporter):
@versionutils.deprecated(as_of=versionutils.deprecated.GRIZZLY, @versionutils.deprecated(as_of=versionutils.deprecated.GRIZZLY,
remove_in=+3) remove_in=+3)
@ -152,27 +156,27 @@ class DeprecatedTestCase(test_base.BaseTestCase):
do_outdated_stuff() do_outdated_stuff()
self.assert_deprecated(mock_log, self.assert_deprecated(mock_reporter,
what='do_outdated_stuff()', what='do_outdated_stuff()',
as_of='Grizzly', as_of='Grizzly',
remove_in='Juno') remove_in='Juno')
@mock.patch('openstack.common.versionutils.LOG') @mock.patch('openstack.common.versionutils.report_deprecated_feature')
def test_deprecated_with_removed_zero(self, mock_log): def test_deprecated_with_removed_zero(self, mock_reporter):
@versionutils.deprecated(as_of=versionutils.deprecated.GRIZZLY, @versionutils.deprecated(as_of=versionutils.deprecated.GRIZZLY,
remove_in=0) remove_in=0)
def do_outdated_stuff(): def do_outdated_stuff():
return return
do_outdated_stuff() do_outdated_stuff()
self.assert_deprecated(mock_log, self.assert_deprecated(mock_reporter,
no_removal=True, no_removal=True,
what='do_outdated_stuff()', what='do_outdated_stuff()',
as_of='Grizzly', as_of='Grizzly',
remove_in='Grizzly') remove_in='Grizzly')
@mock.patch('openstack.common.versionutils.LOG') @mock.patch('openstack.common.versionutils.report_deprecated_feature')
def test_deprecated_with_removed_zero_and_alternative(self, mock_log): def test_deprecated_with_removed_zero_and_alternative(self, mock_reporter):
@versionutils.deprecated(as_of=versionutils.deprecated.GRIZZLY, @versionutils.deprecated(as_of=versionutils.deprecated.GRIZZLY,
in_favor_of='different_stuff()', in_favor_of='different_stuff()',
remove_in=0) remove_in=0)
@ -180,15 +184,15 @@ class DeprecatedTestCase(test_base.BaseTestCase):
return return
do_outdated_stuff() do_outdated_stuff()
self.assert_deprecated(mock_log, self.assert_deprecated(mock_reporter,
no_removal=True, no_removal=True,
what='do_outdated_stuff()', what='do_outdated_stuff()',
as_of='Grizzly', as_of='Grizzly',
in_favor_of='different_stuff()', in_favor_of='different_stuff()',
remove_in='Grizzly') remove_in='Grizzly')
@mock.patch('openstack.common.versionutils.LOG') @mock.patch('openstack.common.versionutils.report_deprecated_feature')
def test_deprecated_class_without_init(self, mock_log): def test_deprecated_class_without_init(self, mock_reporter):
@versionutils.deprecated(as_of=versionutils.deprecated.JUNO, @versionutils.deprecated(as_of=versionutils.deprecated.JUNO,
remove_in=+1) remove_in=+1)
@ -197,13 +201,13 @@ class DeprecatedTestCase(test_base.BaseTestCase):
obj = OutdatedClass() obj = OutdatedClass()
self.assertIsInstance(obj, OutdatedClass) self.assertIsInstance(obj, OutdatedClass)
self.assert_deprecated(mock_log, self.assert_deprecated(mock_reporter,
what='OutdatedClass()', what='OutdatedClass()',
as_of='Juno', as_of='Juno',
remove_in='Kilo') remove_in='Kilo')
@mock.patch('openstack.common.versionutils.LOG') @mock.patch('openstack.common.versionutils.report_deprecated_feature')
def test_deprecated_class_with_init(self, mock_log): def test_deprecated_class_with_init(self, mock_reporter):
mock_arguments = mock.MagicMock() mock_arguments = mock.MagicMock()
args = (1, 5, 7) args = (1, 5, 7)
kwargs = {'first': 10, 'second': 20} kwargs = {'first': 10, 'second': 20}
@ -223,7 +227,7 @@ class DeprecatedTestCase(test_base.BaseTestCase):
self.assertEqual('It is __init__ method.', obj.__init__.__doc__) self.assertEqual('It is __init__ method.', obj.__init__.__doc__)
self.assertEqual(args, mock_arguments.args) self.assertEqual(args, mock_arguments.args)
self.assertEqual(kwargs, mock_arguments.kwargs) self.assertEqual(kwargs, mock_arguments.kwargs)
self.assert_deprecated(mock_log, self.assert_deprecated(mock_reporter,
what='OutdatedClass()', what='OutdatedClass()',
as_of='Juno', as_of='Juno',
remove_in='Kilo') remove_in='Kilo')