# (c) Copyright 2009. CodeWeavers, Inc.
import types
import warnings
#####
#
# @deprecated decorator
#
#####
class _DeprecationDecorator(object):
"""Decorators receive either their parameters or the function to decorate.
So we use this callable class as a trampoline to get both at the same time.
"""
def __init__(self, msg):
self.msg = msg
def __call__(self, func):
def new_func(*args, **kwargs):
warnings.warn("Call to deprecated function %s. %s" %
(func.__name__, self.msg),
category=DeprecationWarning,
stacklevel=2)
return func(*args, **kwargs)
if isinstance(func, (classmethod, staticmethod)):
# Class and static methods behave completely differently from
# regular functions. The easy way out is to reorder the decorators
# so raise an exception with that suggestion.
raise TypeError("Reorder the decorators so @deprecated is closer to the method declaration.")
# Copy the function properties so it looks the same
# pylint: disable=W0622
new_func.__name__ = func.__name__
new_func.__doc__ = func.__doc__
new_func.__dict__.update(func.__dict__)
return new_func
def deprecated(msg=''):
"""This is a decorator which can be used to mark functions as deprecated.
It will result in a warning being emitted when the function is used. The
optional msg parameter can be used to suggest an alternative.
"""
if isinstance(msg, (types.FunctionType, classmethod, staticmethod)):
# The user forgot the parentheses after @deprecated!
return _DeprecationDecorator('').__call__(msg)
return _DeprecationDecorator(msg)
#####
#
# @abstractmethod decorator
#
#####
def abstractmethod(func):
"""This decorator identifies abstract methods and raises an exception if
they are called.
"""
def new_func():
raise NotImplementedError("Attempt to invoke the abstract method %s" % func.__name__)
if not isinstance(func, types.FunctionType):
raise TypeError("@abstractmethod makes no sense on class and static methods.")
# Copy the function properties so it looks the same
# pylint: disable=W0622
new_func.__name__ = func.__name__
new_func.__doc__ = func.__doc__
new_func.__dict__.update(func.__dict__)
return new_func