Exemple #1
0
def moved_function(new_func,
                   old_func_name,
                   old_module_name,
                   message=None,
                   version=None,
                   removal_version=None,
                   stacklevel=3,
                   category=None):
    """Deprecates a function that was moved to another location.

    This generates a wrapper around ``new_func`` that will emit a deprecation
    warning when called. The warning message will include the new location
    to obtain the function from.
    """
    new_func_full_name = _utils.get_callable_name(new_func)
    new_func_full_name += _MOVED_CALLABLE_POSTFIX
    old_func_full_name = ".".join([old_module_name, old_func_name])
    old_func_full_name += _MOVED_CALLABLE_POSTFIX
    prefix = _FUNC_MOVED_PREFIX_TPL % (old_func_full_name, new_func_full_name)
    out_message = _utils.generate_message(prefix,
                                          message=message,
                                          version=version,
                                          removal_version=removal_version)

    @six.wraps(new_func)
    def old_new_func(*args, **kwargs):
        _utils.deprecation(out_message,
                           stacklevel=stacklevel,
                           category=category)
        return new_func(*args, **kwargs)

    old_new_func.__name__ = old_func_name
    old_new_func.__module__ = old_module_name
    return old_new_func
Exemple #2
0
def moved_function(new_func, old_func_name, old_module_name,
                   message=None, version=None, removal_version=None,
                   stacklevel=3, category=None):
    """Deprecates a function that was moved to another location.

    This generates a wrapper around ``new_func`` that will emit a deprecation
    warning when called. The warning message will include the new location
    to obtain the function from.
    """
    new_func_full_name = _utils.get_callable_name(new_func)
    new_func_full_name += _MOVED_CALLABLE_POSTFIX
    old_func_full_name = ".".join([old_module_name, old_func_name])
    old_func_full_name += _MOVED_CALLABLE_POSTFIX
    prefix = _FUNC_MOVED_PREFIX_TPL % (old_func_full_name, new_func_full_name)
    out_message = _utils.generate_message(prefix,
                                          message=message, version=version,
                                          removal_version=removal_version)

    @six.wraps(new_func, assigned=_utils.get_assigned(new_func))
    def old_new_func(*args, **kwargs):
        _utils.deprecation(out_message, stacklevel=stacklevel,
                           category=category)
        return new_func(*args, **kwargs)

    old_new_func.__name__ = old_func_name
    old_new_func.__module__ = old_module_name
    return old_new_func
Exemple #3
0
def moved_class(new_class, old_class_name, old_module_name,
                message=None, version=None, removal_version=None,
                stacklevel=3):
    """Deprecates a class that was moved to another location.

    This creates a 'new-old' type that can be used for a
    deprecation period that can be inherited from. This will emit warnings
    when the old locations class is initialized, telling where the new and
    improved location for the old class now is.
    """

    old_name = ".".join((old_module_name, old_class_name))
    new_name = reflection.get_class_name(new_class)
    prefix = _CLASS_MOVED_PREFIX_TPL % (old_name, new_name)
    out_message = _utils.generate_message(
        prefix, message=message, version=version,
        removal_version=removal_version)

    def decorator(f):

        # Use the older functools until the following is available:
        #
        # https://bitbucket.org/gutworth/six/issue/105

        @functools.wraps(f, assigned=("__name__", "__doc__"))
        def wrapper(self, *args, **kwargs):
            _utils.deprecation(out_message, stacklevel=stacklevel)
            return f(self, *args, **kwargs)

        return wrapper

    old_class = type(old_class_name, (new_class,), {})
    old_class.__module__ = old_module_name
    old_class.__init__ = decorator(old_class.__init__)
    return old_class
Exemple #4
0
def updated_kwarg_default_value(name, old_value, new_value, message=None,
                                version=None, stacklevel=3,
                                category=FutureWarning):

    """Decorates a kwarg accepting function to change the default value"""

    prefix = _KWARG_UPDATED_PREFIX_TPL % (name, new_value)
    postfix = _KWARG_UPDATED_POSTFIX_TPL % old_value
    out_message = _utils.generate_message(
        prefix, postfix=postfix, message=message, version=version)

    def decorator(f):
        sig = get_signature(f)
        varnames = list(six.iterkeys(sig.parameters))

        @wrapt.decorator
        def wrapper(wrapped, instance, args, kwargs):
            explicit_params = set(
                varnames[:len(args)] + list(kwargs.keys())
            )
            allparams = set(varnames)
            default_params = set(allparams - explicit_params)
            if name in default_params:
                _utils.deprecation(out_message,
                                   stacklevel=stacklevel, category=category)
            return wrapped(*args, **kwargs)

        return wrapper(f)

    return decorator
Exemple #5
0
def deprecate(prefix, postfix=None, message=None,
              version=None, removal_version=None,
              stacklevel=3, category=DeprecationWarning):
    """Helper to deprecate some thing using generated message format.

    :param prefix: prefix string used as the prefix of the output message
    :param postfix: postfix string used as the postfix of the output message
    :param message: message string used as ending contents of the deprecate
                    message
    :param version: version string (represents the version this
                    deprecation was created in)
    :param removal_version: version string (represents the version this
                            deprecation will be removed in); a string of '?'
                            will denote this will be removed in some future
                            unknown version
    :param stacklevel: stacklevel used in the :func:`warnings.warn` function
                       to locate where the users code is in the
                       :func:`warnings.warn` call
    :param category: the :mod:`warnings` category to use, defaults to
                     :py:class:`DeprecationWarning` if not provided
    """
    out_message = _utils.generate_message(prefix, postfix=postfix,
                                          version=version, message=message,
                                          removal_version=removal_version)
    _utils.deprecation(out_message, stacklevel=stacklevel,
                       category=category)
Exemple #6
0
def removed_module(module, replacement=None, message=None,
                   version=None, removal_version=None, stacklevel=3):
    """Helper to be called inside a module to emit a deprecation warning

    :param str replacment: A location (or information about) of any potential
                           replacement for the removed module (if applicable)
    :param str message: A message to include in the deprecation warning
    :param str version: Specify what version the removed module is present in
    :param str removal_version: What version the module will be removed. If
                                '?' is used this implies an undefined future
                                version
    :param int stacklevel: How many entries deep in the call stack before
                           ignoring
    """
    if inspect.ismodule(module):
        module_name = _get_module_name(module)
    elif isinstance(module, six.string_types):
        module_name = module
    else:
        _qual, type_name = _get_qualified_name(type(module))
        raise TypeError("Unexpected module type '%s' (expected string or"
                        " module type only)" % type_name)
    prefix = "The '%s' module usage is deprecated" % module_name
    if replacement:
        postfix = ", please use %s instead" % replacement
    else:
        postfix = None
    out_message = _utils.generate_message(prefix,
                                          postfix=postfix, message=message,
                                          version=version,
                                          removal_version=removal_version)
    _utils.deprecation(out_message, stacklevel)
def renamed_kwarg(old_name,
                  new_name,
                  message=None,
                  version=None,
                  removal_version=None,
                  stacklevel=3):
    """Decorates a kwarg accepting function to deprecate a renamed kwarg."""

    prefix = _KWARG_RENAMED_PREFIX_TPL % old_name
    postfix = _KWARG_RENAMED_POSTFIX_TPL % new_name
    out_message = _utils.generate_message(prefix,
                                          postfix=postfix,
                                          message=message,
                                          version=version,
                                          removal_version=removal_version)

    def decorator(f):
        @six.wraps(f)
        def wrapper(*args, **kwargs):
            if old_name in kwargs:
                _utils.deprecation(out_message, stacklevel=stacklevel)
            return f(*args, **kwargs)

        return wrapper

    return decorator
Exemple #8
0
def renamed_kwarg(old_name,
                  new_name,
                  message=None,
                  version=None,
                  removal_version=None,
                  stacklevel=3,
                  category=None,
                  replace=False):
    """Decorates a kwarg accepting function to deprecate a renamed kwarg."""

    prefix = _KWARG_RENAMED_PREFIX_TPL % old_name
    postfix = _KWARG_RENAMED_POSTFIX_TPL % new_name
    out_message = _utils.generate_message(prefix,
                                          postfix=postfix,
                                          message=message,
                                          version=version,
                                          removal_version=removal_version)

    def decorator(f):
        @six.wraps(f, assigned=_utils.get_assigned(f))
        def wrapper(*args, **kwargs):
            if old_name in kwargs:
                _utils.deprecation(out_message,
                                   stacklevel=stacklevel,
                                   category=category)
                if replace:
                    kwargs.setdefault(new_name, kwargs.pop(old_name))
            return f(*args, **kwargs)

        return wrapper

    return decorator
Exemple #9
0
def renamed_kwarg(old_name, new_name, message=None,
                  version=None, removal_version=None, stacklevel=3,
                  category=None, replace=False):
    """Decorates a kwarg accepting function to deprecate a renamed kwarg."""

    prefix = _KWARG_RENAMED_PREFIX_TPL % old_name
    postfix = _KWARG_RENAMED_POSTFIX_TPL % new_name
    out_message = _utils.generate_message(
        prefix, postfix=postfix, message=message, version=version,
        removal_version=removal_version)

    def decorator(f):

        @six.wraps(f, assigned=_utils.get_assigned(f))
        def wrapper(*args, **kwargs):
            if old_name in kwargs:
                _utils.deprecation(out_message,
                                   stacklevel=stacklevel, category=category)
                if replace:
                    kwargs.setdefault(new_name, kwargs.pop(old_name))
            return f(*args, **kwargs)

        return wrapper

    return decorator
Exemple #10
0
def updated_kwarg_default_value(name,
                                old_value,
                                new_value,
                                message=None,
                                version=None,
                                stacklevel=3,
                                category=FutureWarning):
    """Decorates a kwarg accepting function to change the default value"""

    prefix = _KWARG_UPDATED_PREFIX_TPL % (name, new_value)
    postfix = _KWARG_UPDATED_POSTFIX_TPL % old_value
    out_message = _utils.generate_message(prefix,
                                          postfix=postfix,
                                          message=message,
                                          version=version)

    def decorator(f):
        sig = signature(f)
        varnames = list(sig.parameters.keys())

        @wrapt.decorator
        def wrapper(wrapped, instance, args, kwargs):
            explicit_params = set(varnames[:len(args)] + list(kwargs.keys()))
            allparams = set(varnames)
            default_params = set(allparams - explicit_params)
            if name in default_params:
                _utils.deprecation(out_message,
                                   stacklevel=stacklevel,
                                   category=category)
            return wrapped(*args, **kwargs)

        return wrapper(f)

    return decorator
Exemple #11
0
 def _cls_decorator(cls):
     _check_it(cls)
     out_message = _utils.generate_message(
         "Using class '%s' (either directly or via inheritance)"
         " is deprecated" % cls_name, postfix=None, message=message,
         version=version, removal_version=removal_version)
     cls.__init__ = _wrap_it(cls.__init__, out_message)
     return cls
Exemple #12
0
 def __init__(self, old_name, new_name,
              version=None, removal_version=None,
              stacklevel=3, category=None):
     self._old_name = old_name
     self._new_name = new_name
     self._message = _utils.generate_message(
         "Read-only property '%s' has moved"
         " to '%s'" % (self._old_name, self._new_name),
         version=version, removal_version=removal_version)
     self._stacklevel = stacklevel
     self._category = category
 def wrapper(f, instance, args, kwargs):
     qualified, f_name = _utils.get_qualified_name(f)
     if qualified:
         if inspect.isclass(f):
             prefix_pre = "Using class"
             thing_post = ''
         else:
             prefix_pre = "Using function/method"
             thing_post = '()'
     if not qualified:
         prefix_pre = "Using function/method"
         base_name = None
         if instance is None:
             # Decorator was used on a class
             if inspect.isclass(f):
                 prefix_pre = "Using class"
                 thing_post = ''
                 module_name = _get_module_name(inspect.getmodule(f))
                 if module_name == '__main__':
                     f_name = _utils.get_class_name(
                         f, fully_qualified=False)
                 else:
                     f_name = _utils.get_class_name(
                         f, fully_qualified=True)
             # Decorator was a used on a function
             else:
                 thing_post = '()'
                 module_name = _get_module_name(inspect.getmodule(f))
                 if module_name != '__main__':
                     f_name = _utils.get_callable_name(f)
         # Decorator was used on a classmethod or instancemethod
         else:
             thing_post = '()'
             base_name = _utils.get_class_name(instance,
                                               fully_qualified=False)
         if base_name:
             thing_name = ".".join([base_name, f_name])
         else:
             thing_name = f_name
     else:
         thing_name = f_name
     if thing_post:
         thing_name += thing_post
     prefix = prefix_pre + " '%s' is deprecated" % (thing_name)
     out_message = _utils.generate_message(
         prefix,
         version=version,
         removal_version=removal_version,
         message=message)
     _utils.deprecation(out_message,
                        stacklevel=stacklevel, category=category)
     return f(*args, **kwargs)
Exemple #14
0
 def wrapper(f, instance, args, kwargs):
     qualified, f_name = _utils.get_qualified_name(f)
     if qualified:
         if inspect.isclass(f):
             prefix_pre = "Using class"
             thing_post = ''
         else:
             prefix_pre = "Using function/method"
             thing_post = '()'
     if not qualified:
         prefix_pre = "Using function/method"
         base_name = None
         if instance is None:
             # Decorator was used on a class
             if inspect.isclass(f):
                 prefix_pre = "Using class"
                 thing_post = ''
                 module_name = _get_qualified_name(inspect.getmodule(f))
                 if module_name == '__main__':
                     f_name = _utils.get_class_name(
                         f, fully_qualified=False)
                 else:
                     f_name = _utils.get_class_name(
                         f, fully_qualified=True)
             # Decorator was a used on a function
             else:
                 thing_post = '()'
                 module_name = _get_qualified_name(inspect.getmodule(f))
                 if module_name != '__main__':
                     f_name = _utils.get_callable_name(f)
         # Decorator was used on a classmethod or instancemethod
         else:
             thing_post = '()'
             base_name = _utils.get_class_name(instance,
                                               fully_qualified=False)
         if base_name:
             thing_name = ".".join([base_name, f_name])
         else:
             thing_name = f_name
     else:
         thing_name = f_name
     if thing_post:
         thing_name += thing_post
     prefix = prefix_pre + " '%s' is deprecated" % (thing_name)
     out_message = _utils.generate_message(
         prefix,
         version=version,
         removal_version=removal_version,
         message=message)
     _utils.deprecation(out_message,
                        stacklevel=stacklevel, category=category)
     return f(*args, **kwargs)
Exemple #15
0
 def _fetch_message_from_cache(self, kind):
     try:
         out_message = self._message_cache[kind]
     except KeyError:
         prefix_tpl = self._PROPERTY_GONE_TPLS[kind]
         prefix = prefix_tpl % _fetch_first_result(
             self.fget, self.fset, self.fdel, _get_qualified_name,
             value_not_found="???")
         out_message = _utils.generate_message(
             prefix, message=self.message, version=self.version,
             removal_version=self.removal_version)
         self._message_cache[kind] = out_message
     return out_message
Exemple #16
0
 def wrapper(self, *args, **kwargs):
     base_name = reflection.get_class_name(self, fully_qualified=False)
     if fully_qualified:
         old_name = old_attribute_name
     else:
         old_name = ".".join((base_name, old_attribute_name))
     new_name = ".".join((base_name, new_attribute_name))
     prefix = _KIND_MOVED_PREFIX_TPL % (kind, old_name, new_name)
     out_message = _utils.generate_message(
         prefix, message=message,
         version=version, removal_version=removal_version)
     _utils.deprecation(out_message, stacklevel=stacklevel)
     return f(self, *args, **kwargs)
    def wrapper(f, instance, args, kwargs):
        try:
            # Prefer the py3.x name (if we can get at it...)
            f_name = f.__qualname__
            qualified = True
            if inspect.isclass(f):
                _prefix_pre = "Using class"
            else:
                _prefix_pre = "Using function/method"
        except AttributeError:
            f_name = f.__name__
            qualified = False

        if not qualified:
            _prefix_pre = "Using function/method"
            if instance is None:
                # Decorator was used on a class
                if inspect.isclass(f):
                    _prefix_pre = "Using class"
                    module_name = inspect.getmodule(f).__name__
                    if module_name == '__main__':
                        f_name = reflection.get_class_name(
                            f, fully_qualified=False)
                    else:
                        f_name = reflection.get_class_name(
                            f, fully_qualified=True)
                    base_name = None
                # Decorator was a used on a function
                else:
                    module_name = inspect.getmodule(f).__name__
                    if module_name != '__main__':
                        f_name = reflection.get_callable_name(f)
                    base_name = None
            # Decorator was used on a classmethod or instancemethod
            else:
                base_name = reflection.get_class_name(instance,
                                                      fully_qualified=False)
            if base_name:
                function_name = ".".join([base_name, f_name])
            else:
                function_name = f_name
        else:
            function_name = f_name
        _prefix = _prefix_pre + " %s is deprecated" % function_name
        out_message = _utils.generate_message(_prefix,
                                              version=version,
                                              removal_version=removal_version,
                                              message=message)
        _utils.deprecation(out_message, stacklevel)
        return f(*args, **kwargs)
def removed_kwarg(old_name, message=None, version=None, removal_version=None, stacklevel=3, category=None):
    """Decorates a kwarg accepting function to deprecate a removed kwarg."""

    prefix = "Using the '%s' argument is deprecated" % old_name
    out_message = _utils.generate_message(
        prefix, postfix=None, message=message, version=version, removal_version=removal_version
    )

    @wrapt.decorator
    def wrapper(f, instance, args, kwargs):
        if old_name in kwargs:
            _utils.deprecation(out_message, stacklevel=stacklevel, category=category)
        return f(*args, **kwargs)

    return wrapper
Exemple #19
0
 def wrapper(self, *args, **kwargs):
     base_name = reflection.get_class_name(self, fully_qualified=False)
     if fully_qualified:
         old_name = old_attribute_name
     else:
         old_name = ".".join((base_name, old_attribute_name))
     new_name = ".".join((base_name, new_attribute_name))
     prefix = _KIND_MOVED_PREFIX_TPL % (kind, old_name, new_name)
     out_message = _utils.generate_message(
         prefix,
         message=message,
         version=version,
         removal_version=removal_version)
     _utils.deprecation(out_message, stacklevel=stacklevel)
     return f(self, *args, **kwargs)
Exemple #20
0
 def __init__(self,
              old_name,
              new_name,
              version=None,
              removal_version=None,
              stacklevel=3,
              category=None):
     self._old_name = old_name
     self._new_name = new_name
     self._message = _utils.generate_message(
         "Read-only property '%s' has moved"
         " to '%s'" % (self._old_name, self._new_name),
         version=version,
         removal_version=removal_version)
     self._stacklevel = stacklevel
     self._category = category
Exemple #21
0
def removed_kwarg(old_name, message=None,
                  version=None, removal_version=None, stacklevel=3,
                  category=None):
    """Decorates a kwarg accepting function to deprecate a removed kwarg."""

    prefix = "Using the '%s' argument is deprecated" % old_name
    out_message = _utils.generate_message(
        prefix, postfix=None, message=message, version=version,
        removal_version=removal_version)

    @wrapt.decorator
    def wrapper(f, instance, args, kwargs):
        if old_name in kwargs:
            _utils.deprecation(out_message,
                               stacklevel=stacklevel, category=category)
        return f(*args, **kwargs)

    return wrapper
Exemple #22
0
def moved_class(new_class,
                old_class_name,
                old_module_name,
                message=None,
                version=None,
                removal_version=None,
                stacklevel=3,
                category=None):
    """Deprecates a class that was moved to another location.

    This creates a 'new-old' type that can be used for a
    deprecation period that can be inherited from. This will emit warnings
    when the old locations class is initialized, telling where the new and
    improved location for the old class now is.
    """

    if not inspect.isclass(new_class):
        _qual, type_name = _utils.get_qualified_name(type(new_class))
        raise TypeError("Unexpected class type '%s' (expected"
                        " class type only)" % type_name)

    old_name = ".".join((old_module_name, old_class_name))
    new_name = _utils.get_class_name(new_class)
    prefix = _CLASS_MOVED_PREFIX_TPL % (old_name, new_name)
    out_message = _utils.generate_message(prefix,
                                          message=message,
                                          version=version,
                                          removal_version=removal_version)

    def decorator(f):
        @six.wraps(f, assigned=("__name__", "__doc__"))
        def wrapper(self, *args, **kwargs):
            _utils.deprecation(out_message,
                               stacklevel=stacklevel,
                               category=category)
            return f(self, *args, **kwargs)

        return wrapper

    old_class = type(old_class_name, (new_class, ), {})
    old_class.__module__ = old_module_name
    old_class.__init__ = decorator(old_class.__init__)
    return old_class
Exemple #23
0
def removed_kwarg(old_name, message=None,
                  version=None, removal_version=None, stacklevel=3):
    """Decorates a kwarg accepting function to deprecate a removed kwarg."""

    prefix = "Using the '%s' argument is deprecated" % old_name
    out_message = _utils.generate_message(
        prefix, postfix=None, message=message, version=version,
        removal_version=removal_version)

    def decorator(f):

        @six.wraps(f)
        def wrapper(*args, **kwargs):
            if old_name in kwargs:
                _utils.deprecation(out_message, stacklevel=stacklevel)
            return f(*args, **kwargs)

        return wrapper

    return decorator
Exemple #24
0
def renamed_kwarg(old_name, new_name, message=None,
                  version=None, removal_version=None, stacklevel=3):
    """Decorates a kwarg accepting function to deprecate a renamed kwarg."""

    prefix = _KWARG_RENAMED_PREFIX_TPL % old_name
    postfix = _KWARG_RENAMED_POSTFIX_TPL % new_name
    out_message = _utils.generate_message(
        prefix, postfix=postfix, message=message, version=version,
        removal_version=removal_version)

    def decorator(f):

        @six.wraps(f)
        def wrapper(*args, **kwargs):
            if old_name in kwargs:
                _utils.deprecation(out_message, stacklevel=stacklevel)
            return f(*args, **kwargs)

        return wrapper

    return decorator
Exemple #25
0
def moved_class(new_class,
                old_class_name,
                old_module_name,
                message=None,
                version=None,
                removal_version=None,
                stacklevel=3):
    """Deprecates a class that was moved to another location.

    This creates a 'new-old' type that can be used for a
    deprecation period that can be inherited from. This will emit warnings
    when the old locations class is initialized, telling where the new and
    improved location for the old class now is.
    """

    old_name = ".".join((old_module_name, old_class_name))
    new_name = reflection.get_class_name(new_class)
    prefix = _CLASS_MOVED_PREFIX_TPL % (old_name, new_name)
    out_message = _utils.generate_message(prefix,
                                          message=message,
                                          version=version,
                                          removal_version=removal_version)

    def decorator(f):

        # Use the older functools until the following is available:
        #
        # https://bitbucket.org/gutworth/six/issue/105

        @functools.wraps(f, assigned=("__name__", "__doc__"))
        def wrapper(self, *args, **kwargs):
            _utils.deprecation(out_message, stacklevel=stacklevel)
            return f(self, *args, **kwargs)

        return wrapper

    old_class = type(old_class_name, (new_class, ), {})
    old_class.__module__ = old_module_name
    old_class.__init__ = decorator(old_class.__init__)
    return old_class
Exemple #26
0
def removed_module(module,
                   replacement=None,
                   message=None,
                   version=None,
                   removal_version=None,
                   stacklevel=3,
                   category=None):
    """Helper to be called inside a module to emit a deprecation warning

    :param str replacment: A location (or information about) of any potential
                           replacement for the removed module (if applicable)
    :param str message: A message to include in the deprecation warning
    :param str version: Specify what version the removed module is present in
    :param str removal_version: What version the module will be removed. If
                                '?' is used this implies an undefined future
                                version
    :param int stacklevel: How many entries deep in the call stack before
                           ignoring
    :param type category: warnings message category (this defaults to
                          ``DeprecationWarning`` when none is provided)
    """
    if inspect.ismodule(module):
        module_name = _get_module_name(module)
    elif isinstance(module, six.string_types):
        module_name = module
    else:
        _qual, type_name = _utils.get_qualified_name(type(module))
        raise TypeError("Unexpected module type '%s' (expected string or"
                        " module type only)" % type_name)
    prefix = "The '%s' module usage is deprecated" % module_name
    if replacement:
        postfix = ", please use %s instead" % replacement
    else:
        postfix = None
    out_message = _utils.generate_message(prefix,
                                          postfix=postfix,
                                          message=message,
                                          version=version,
                                          removal_version=removal_version)
    _utils.deprecation(out_message, stacklevel=stacklevel, category=category)
Exemple #27
0
def moved_class(new_class, old_class_name, old_module_name,
                message=None, version=None, removal_version=None,
                stacklevel=3, category=None):
    """Deprecates a class that was moved to another location.

    This creates a 'new-old' type that can be used for a
    deprecation period that can be inherited from. This will emit warnings
    when the old locations class is initialized, telling where the new and
    improved location for the old class now is.
    """

    if not inspect.isclass(new_class):
        _qual, type_name = _utils.get_qualified_name(type(new_class))
        raise TypeError("Unexpected class type '%s' (expected"
                        " class type only)" % type_name)

    old_name = ".".join((old_module_name, old_class_name))
    new_name = _utils.get_class_name(new_class)
    prefix = _CLASS_MOVED_PREFIX_TPL % (old_name, new_name)
    out_message = _utils.generate_message(
        prefix, message=message, version=version,
        removal_version=removal_version)

    def decorator(f):

        @six.wraps(f, assigned=_utils.get_assigned(f))
        def wrapper(self, *args, **kwargs):
            _utils.deprecation(out_message, stacklevel=stacklevel,
                               category=category)
            return f(self, *args, **kwargs)

        return wrapper

    old_class = type(old_class_name, (new_class,), {})
    old_class.__module__ = old_module_name
    old_class.__init__ = decorator(old_class.__init__)
    return old_class