Add get_callable_name utility function

Code that makes name from a callable was moved from functor
task to utils and enhanced to better support more use cases.

Change-Id: I1280a31553c5051079e60b31cd1796f51485f040
This commit is contained in:
Ivan A. Melnikov
2013-08-27 17:07:20 +04:00
committed by Joshua Harlow
parent 0fa642d949
commit fbd06b552e
3 changed files with 88 additions and 11 deletions

View File

@@ -88,16 +88,6 @@ class FunctorTask(Task):
Take any callable and make a task from it.
"""
@staticmethod
def _get_callable_name(execute_with):
"""Generate a name from callable"""
im_class = getattr(execute_with, 'im_class', None)
if im_class is not None:
parts = (im_class.__module__, im_class.__name__,
execute_with.__name__)
else:
parts = (execute_with.__module__, execute_with.__name__)
return '.'.join(parts)
def __init__(self, execute_with, **kwargs):
"""Initialize FunctorTask instance with given callable and kwargs
@@ -115,7 +105,7 @@ class FunctorTask(Task):
"""
name = kwargs.pop('name', None)
if name is None:
name = self._get_callable_name(execute_with)
name = utils.get_callable_name(execute_with)
super(FunctorTask, self).__init__(name)
self._execute_with = execute_with
self._revert_with = kwargs.pop('revert_with', None)

View File

@@ -56,3 +56,67 @@ class UtilTest(test.TestCase):
pass
self.assertEquals(10, len(accum))
self.assertEquals(10, len(context))
def mere_function():
pass
class Class(object):
def __init__(self):
pass
def method(self):
pass
@staticmethod
def static_method():
pass
@classmethod
def class_method():
pass
class CallableClass(object):
def __call__(self):
pass
class GetCallableNameTest(test.TestCase):
def test_mere_function(self):
name = utils.get_callable_name(mere_function)
self.assertEquals(name, '.'.join((__name__, 'mere_function')))
def test_method(self):
name = utils.get_callable_name(Class.method)
self.assertEquals(name, '.'.join((__name__, 'Class', 'method')))
def test_instance_method(self):
name = utils.get_callable_name(Class().method)
self.assertEquals(name, '.'.join((__name__, 'Class', 'method')))
def test_static_method(self):
# NOTE(imelnikov): static method are just functions, class name
# is not recorded anywhere in them
name = utils.get_callable_name(Class.static_method)
self.assertEquals(name, '.'.join((__name__, 'static_method')))
def test_class_method(self):
name = utils.get_callable_name(Class.class_method)
self.assertEquals(name, '.'.join((__name__, 'Class', 'class_method')))
def test_constructor(self):
name = utils.get_callable_name(Class)
self.assertEquals(name, '.'.join((__name__, 'Class')))
def test_callable_class(self):
name = utils.get_callable_name(CallableClass())
self.assertEquals(name, '.'.join((__name__, 'CallableClass')))
def test_callable_class_call(self):
name = utils.get_callable_name(CallableClass().__call__)
self.assertEquals(name, '.'.join((__name__, 'CallableClass',
'__call__')))

View File

@@ -26,6 +26,7 @@ import sys
import threading
import threading2
import time
import types
from taskflow.openstack.common import uuidutils
@@ -52,6 +53,28 @@ def await(check_functor, timeout=None):
return True
def get_callable_name(function):
"""Generate a name from callable
Tries to do the best to guess fully qualified callable name.
"""
im_class = getattr(function, 'im_class', None)
if im_class is not None:
if im_class is type:
# this is bound class method
im_class = function.im_self
parts = (im_class.__module__, im_class.__name__,
function.__name__)
elif isinstance(function, types.FunctionType):
parts = (function.__module__, function.__name__)
else:
im_class = type(function)
if im_class is type:
im_class = function
parts = (im_class.__module__, im_class.__name__)
return '.'.join(parts)
def get_task_version(task):
"""Gets a tasks *string* version, whether it is a task object/function."""
task_version = getattr(task, 'version')