Merge "Log deprecation message when catching deprecated exceptions"
This commit is contained in:
@@ -232,6 +232,73 @@ class DeprecatedTestCase(test_base.BaseTestCase):
|
||||
as_of='Juno',
|
||||
remove_in='Kilo')
|
||||
|
||||
@mock.patch('oslo_log.versionutils.report_deprecated_feature')
|
||||
def test_deprecated_exception(self, mock_log):
|
||||
@versionutils.deprecated(as_of=versionutils.deprecated.ICEHOUSE,
|
||||
remove_in=+1)
|
||||
class OldException(Exception):
|
||||
pass
|
||||
|
||||
class NewException(OldException):
|
||||
pass
|
||||
|
||||
try:
|
||||
raise NewException()
|
||||
except OldException:
|
||||
pass
|
||||
|
||||
self.assert_deprecated(mock_log, what='OldException()',
|
||||
as_of='Icehouse', remove_in='Juno')
|
||||
|
||||
@mock.patch('oslo_log.versionutils.report_deprecated_feature')
|
||||
def test_deprecated_exception_old(self, mock_log):
|
||||
@versionutils.deprecated(as_of=versionutils.deprecated.ICEHOUSE,
|
||||
remove_in=+1)
|
||||
class OldException(Exception):
|
||||
pass
|
||||
|
||||
try:
|
||||
raise OldException()
|
||||
except OldException:
|
||||
pass
|
||||
|
||||
self.assert_deprecated(mock_log, what='OldException()',
|
||||
as_of='Icehouse', remove_in='Juno')
|
||||
|
||||
@mock.patch('oslo_log.versionutils.report_deprecated_feature')
|
||||
def test_deprecated_exception_new(self, mock_log):
|
||||
@versionutils.deprecated(as_of=versionutils.deprecated.ICEHOUSE,
|
||||
remove_in=+1)
|
||||
class OldException(Exception):
|
||||
pass
|
||||
|
||||
class NewException(OldException):
|
||||
pass
|
||||
|
||||
try:
|
||||
raise NewException()
|
||||
except NewException:
|
||||
pass
|
||||
|
||||
mock_log.assert_not_called()
|
||||
|
||||
@mock.patch('oslo_log.versionutils.report_deprecated_feature')
|
||||
def test_deprecated_exception_unrelated(self, mock_log):
|
||||
@versionutils.deprecated(as_of=versionutils.deprecated.ICEHOUSE,
|
||||
remove_in=+1)
|
||||
class OldException(Exception):
|
||||
pass
|
||||
|
||||
class UnrelatedException(Exception):
|
||||
pass
|
||||
|
||||
try:
|
||||
raise UnrelatedException()
|
||||
except UnrelatedException:
|
||||
pass
|
||||
|
||||
mock_log.assert_not_called()
|
||||
|
||||
|
||||
class IsCompatibleTestCase(test_base.BaseTestCase):
|
||||
def test_same_version(self):
|
||||
|
||||
@@ -31,6 +31,7 @@ from oslo_log._i18n import _
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
CONF = cfg.CONF
|
||||
_DEPRECATED_EXCEPTIONS = set()
|
||||
|
||||
|
||||
deprecated_opts = [
|
||||
@@ -52,7 +53,9 @@ class deprecated(object):
|
||||
This decorator logs a deprecation message when the callable it decorates is
|
||||
used. The message will include the release where the callable was
|
||||
deprecated, the release where it may be removed and possibly an optional
|
||||
replacement.
|
||||
replacement. It also logs a message when a deprecated exception is being
|
||||
caught in a try-except block, but not when subclasses of that exception
|
||||
are being caught.
|
||||
|
||||
Examples:
|
||||
|
||||
@@ -160,6 +163,16 @@ class deprecated(object):
|
||||
report_deprecated_feature(LOG, msg, details)
|
||||
orig_init(self, *args, **kwargs)
|
||||
func_or_cls.__init__ = new_init
|
||||
|
||||
if issubclass(func_or_cls, Exception):
|
||||
class ExceptionMeta(type):
|
||||
def __subclasscheck__(self, subclass):
|
||||
if self in _DEPRECATED_EXCEPTIONS:
|
||||
report_deprecated_feature(LOG, msg, details)
|
||||
return super(ExceptionMeta,
|
||||
self).__subclasscheck__(subclass)
|
||||
func_or_cls = six.add_metaclass(ExceptionMeta)(func_or_cls)
|
||||
_DEPRECATED_EXCEPTIONS.add(func_or_cls)
|
||||
return func_or_cls
|
||||
else:
|
||||
raise TypeError('deprecated can be used only with functions or '
|
||||
|
||||
Reference in New Issue
Block a user