Add a moved_inheritable_class deprecation helper

For cases where inheritance is still needed we should provide
a mechanism to provide this so that consuming users of the
library can still refer to the old location for a period of time
so that there derived code does not fail due to the movement
of the class that occurred.

Change-Id: I8cd5b707125264f6b595d5b3ac327cfe16e7923c
This commit is contained in:
Joshua Harlow
2014-12-05 14:28:21 -08:00
parent 1c7d242033
commit a440ec40a5

View File

@@ -14,6 +14,7 @@
# License for the specific language governing permissions and limitations
# under the License.
import functools
import warnings
import six
@@ -202,6 +203,45 @@ def moved_property(new_attribute_name, message=None,
stacklevel=stacklevel)
def moved_inheritable_class(new_class, old_class_name, old_module_name,
message=None, version=None, removal_version=None):
"""Deprecates a class that was moved to another location.
NOTE(harlowja): this creates a new-old type that can be used for a
deprecation period that can be inherited from, the difference between this
and the ``moved_class`` deprecation function is that the proxy from that
function can not be inherited from (thus limiting its use for a more
particular usecase where inheritance is not needed).
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 = _generate_moved_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):
deprecation(out_message, stacklevel=3)
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
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.