Remove oslo.utils dependency

There are two reasons to remove oslo.utils:

 * oslo.utils brings in a number of dependencies that are not required
   by any debtcollector code paths. This is a concern for having
   debtcollector be adopted by libraries that want to maintain minimal
   external requirements.

 * oslo.utils now has a dependency on debtcollector. While this doesn't
   seem to cause any problems with pip it is a weird circular dependency
   that is best to break.

Copy the required reflection methods from oslo.utils to debtcollector
and the associated tests and remove the oslo.utils dependency.

Change-Id: Id4d8f4f7466775d099ab1e82b38605e98e6d840d
This commit is contained in:
Jamie Lennox 2015-05-26 16:05:06 +10:00
parent 8685171362
commit 8f4100aac7
4 changed files with 104 additions and 10 deletions

View File

@ -14,8 +14,23 @@
# License for the specific language governing permissions and limitations
# under the License.
import inspect
import types
import warnings
import six
try:
_TYPE_TYPE = types.TypeType
except AttributeError:
_TYPE_TYPE = type
# See: https://docs.python.org/2/library/__builtin__.html#module-__builtin__
# and see https://docs.python.org/2/reference/executionmodel.html (and likely
# others)...
_BUILTIN_MODULES = ('builtins', '__builtin__', '__builtins__', 'exceptions')
def deprecation(message, stacklevel=None, category=None):
"""Warns about some type of deprecation that has been (or will be) made.
@ -68,3 +83,85 @@ def generate_message(prefix, postfix=None, message=None,
if message:
message_components.append(": %s" % message)
return ''.join(message_components)
def get_class_name(obj, fully_qualified=True):
"""Get class name for object.
If object is a type, fully qualified name of the type is returned.
Else, fully qualified name of the type of the object is returned.
For builtin types, just name is returned.
"""
if not isinstance(obj, six.class_types):
obj = type(obj)
try:
built_in = obj.__module__ in _BUILTIN_MODULES
except AttributeError:
pass
else:
if built_in:
try:
return obj.__qualname__
except AttributeError:
return obj.__name__
pieces = []
try:
pieces.append(obj.__qualname__)
except AttributeError:
pieces.append(obj.__name__)
if fully_qualified:
try:
pieces.insert(0, obj.__module__)
except AttributeError:
pass
return '.'.join(pieces)
def get_method_self(method):
"""Gets the ``self`` object attached to this method (or none)."""
if not inspect.ismethod(method):
return None
try:
return six.get_method_self(method)
except AttributeError:
return None
def get_callable_name(function):
"""Generate a name from callable.
Tries to do the best to guess fully qualified callable name.
"""
method_self = get_method_self(function)
if method_self is not None:
# This is a bound method.
if isinstance(method_self, six.class_types):
# This is a bound class method.
im_class = method_self
else:
im_class = type(method_self)
try:
parts = (im_class.__module__, function.__qualname__)
except AttributeError:
parts = (im_class.__module__, im_class.__name__, function.__name__)
elif inspect.ismethod(function) or inspect.isfunction(function):
# This could be a function, a static method, a unbound method...
try:
parts = (function.__module__, function.__qualname__)
except AttributeError:
if hasattr(function, 'im_class'):
# This is a unbound method, which exists only in python 2.x
im_class = function.im_class
parts = (im_class.__module__,
im_class.__name__, function.__name__)
else:
parts = (function.__module__, function.__name__)
else:
im_class = type(function)
if im_class is _TYPE_TYPE:
im_class = function
try:
parts = (im_class.__module__, im_class.__qualname__)
except AttributeError:
parts = (im_class.__module__, im_class.__name__)
return '.'.join(parts)

View File

@ -16,7 +16,6 @@
import inspect
from oslo_utils import reflection
import six
from debtcollector import _utils
@ -38,7 +37,7 @@ def _moved_decorator(kind, new_attribute_name, message=None,
@six.wraps(f)
def wrapper(self, *args, **kwargs):
base_name = reflection.get_class_name(self, fully_qualified=False)
base_name = _utils.get_class_name(self, fully_qualified=False)
if fully_qualified:
old_name = old_attribute_name
else:
@ -96,7 +95,7 @@ def moved_class(new_class, old_class_name, old_module_name,
" class type only)" % type_name)
old_name = ".".join((old_module_name, old_class_name))
new_name = reflection.get_class_name(new_class)
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,

View File

@ -15,7 +15,6 @@
import functools
import inspect
from oslo_utils import reflection
import six
import wrapt
@ -67,22 +66,22 @@ def remove(f=None, message=None, version=None, removal_version=None,
thing_post = ''
module_name = _get_module_name(inspect.getmodule(f))
if module_name == '__main__':
f_name = reflection.get_class_name(
f_name = _utils.get_class_name(
f, fully_qualified=False)
else:
f_name = reflection.get_class_name(
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 = reflection.get_callable_name(f)
f_name = _utils.get_callable_name(f)
# Decorator was used on a classmethod or instancemethod
else:
thing_post = '()'
base_name = reflection.get_class_name(instance,
fully_qualified=False)
base_name = _utils.get_class_name(instance,
fully_qualified=False)
if base_name:
thing_name = ".".join([base_name, f_name])
else:

View File

@ -5,5 +5,4 @@
pbr>=0.11,<2.0
Babel>=1.3
six>=1.9.0
oslo.utils>=1.4.0 # Apache-2.0
wrapt>=1.7.0 # BSD License