Current File : //opt/eff.org/certbot/venv/lib64/python2.7/site-packages/zope/deprecation/deprecation.py |
##############################################################################
#
# Copyright (c) 2005 Zope Foundation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Deprecation Support
This module provides utilities to ease the development of backward-compatible
code.
"""
__docformat__ = "reStructuredText"
import sys
import types
import warnings
str_and_sequence_types = (str if str is not bytes else basestring, list, tuple)
class ShowSwitch(object):
"""Simple stack-based switch."""
def __init__(self):
self.stack = []
def on(self):
self.stack.pop()
def off(self):
self.stack.append(False)
def reset(self):
self.stack = []
def __call__(self):
return self.stack == []
def __repr__(self):
return '<ShowSwitch %s>' %(self() and 'on' or 'off')
# This attribute can be used to temporarly deactivate deprecation
# warnings, so that backward-compatibility code can import other
# backward-compatiblity components without warnings being produced.
__show__ = ShowSwitch()
class Suppressor(object):
def __enter__(self):
__show__.off()
def __exit__(self, *ignored):
__show__.on()
ogetattr = object.__getattribute__
class DeprecationProxy(object):
def __init__(self, module):
self.__original_module = module
self.__deprecated = {}
def deprecate(self, names, message, cls=DeprecationWarning):
"""Deprecate the given names."""
if not isinstance(names, (tuple, list)):
names = (names,)
for name in names:
self.__deprecated[name] = (message, cls)
def __getattribute__(self, name):
if name == 'deprecate' or name.startswith('_DeprecationProxy__'):
return ogetattr(self, name)
if name == '__class__':
return types.ModuleType
if name in ogetattr(self, '_DeprecationProxy__deprecated'):
if __show__():
msg, cls = self.__deprecated[name]
warnings.warn(name + ': ' + msg, cls, 2)
return getattr(ogetattr(self, '_DeprecationProxy__original_module'),
name)
def __setattr__(self, name, value):
if name.startswith('_DeprecationProxy__'):
return object.__setattr__(self, name, value)
setattr(self.__original_module, name, value)
def __delattr__(self, name):
if name.startswith('_DeprecationProxy__'):
return object.__delattr__(self, name)
delattr(self.__original_module, name)
class DeprecatedModule(object):
def __init__(self, module, msg, cls=DeprecationWarning):
self.__original_module = module
self.__msg = msg
self.__cls = cls
def __getattribute__(self, name):
if name.startswith('_DeprecatedModule__'):
return ogetattr(self, name)
if name == '__class__':
return types.ModuleType
if __show__():
warnings.warn(self.__msg, self.__cls, 2)
return getattr(ogetattr(self, '_DeprecatedModule__original_module'),
name)
def __setattr__(self, name, value):
if name.startswith('_DeprecatedModule__'):
return object.__setattr__(self, name, value)
setattr(self.__original_module, name, value)
def __delattr__(self, name):
if name.startswith('_DeprecatedModule__'):
return object.__delattr__(self, name)
delattr(self.__original_module, name)
class DeprecatedGetProperty(object):
def __init__(self, prop, message, cls=DeprecationWarning):
self.message = message
self.prop = prop
self.cls = cls
def __get__(self, inst, klass):
if __show__():
warnings.warn(self.message, self.cls, 2)
return self.prop.__get__(inst, klass)
class DeprecatedGetSetProperty(DeprecatedGetProperty):
def __set__(self, inst, prop):
if __show__():
warnings.warn(self.message, self.cls, 2)
self.prop.__set__(inst, prop)
class DeprecatedGetSetDeleteProperty(DeprecatedGetSetProperty):
def __delete__(self, inst):
if __show__():
warnings.warn(self.message, self.cls, 2)
self.prop.__delete__(inst)
def DeprecatedMethod(method, message, cls=DeprecationWarning):
def deprecated_method(*args, **kw):
if __show__():
warnings.warn(message, cls, 2)
return method(*args, **kw)
return deprecated_method
def deprecated(specifier, message, cls=DeprecationWarning):
"""Deprecate the given names."""
# A string specifier (or list of strings) means we're called
# top-level in a module and are to deprecate things inside this
# module
if isinstance(specifier, str_and_sequence_types):
globals = sys._getframe(1).f_globals
modname = globals['__name__']
if not isinstance(sys.modules[modname], DeprecationProxy):
sys.modules[modname] = DeprecationProxy(sys.modules[modname])
sys.modules[modname].deprecate(specifier, message, cls)
# Anything else can mean the specifier is a function/method,
# module, or just an attribute of a class
elif isinstance(specifier, types.FunctionType):
return DeprecatedMethod(specifier, message, cls)
elif isinstance(specifier, types.ModuleType):
return DeprecatedModule(specifier, message, cls)
else:
prop = specifier
if hasattr(prop, '__get__') and hasattr(prop, '__set__') and \
hasattr(prop, '__delete__'):
return DeprecatedGetSetDeleteProperty(prop, message, cls)
elif hasattr(prop, '__get__') and hasattr(prop, '__set__'):
return DeprecatedGetSetProperty(prop, message, cls)
elif hasattr(prop, '__get__'):
return DeprecatedGetProperty(prop, message, cls)
class deprecate(object):
"""Deprecation decorator"""
def __init__(self, msg, cls=DeprecationWarning):
self.msg = msg
self.cls = cls
def __call__(self, func):
return DeprecatedMethod(func, self.msg, self.cls)
def moved(to_location, unsupported_in=None, cls=DeprecationWarning):
old = sys._getframe(1).f_globals['__name__']
message = '%s has moved to %s.' % (old, to_location)
if unsupported_in:
message += " Import of %s will become unsupported in %s" % (
old, unsupported_in)
warnings.warn(message, cls, 3)
__import__(to_location)
fromdict = sys.modules[to_location].__dict__
tomod = sys.modules[old]
tomod.__doc__ = message
for name, v in fromdict.items():
if name not in tomod.__dict__:
setattr(tomod, name, v)