Skip to content

Instantly share code, notes, and snippets.

@agronholm
Last active August 29, 2015 14:07
Show Gist options
  • Save agronholm/a41ec3d990a28ed65a0b to your computer and use it in GitHub Desktop.
Save agronholm/a41ec3d990a28ed65a0b to your computer and use it in GitHub Desktop.
Dotted path resolution and tests
def get_callable_name(func):
"""
Returns the best available display name for the given function/callable.
:rtype: str
"""
# the easy case (on Python 3.3+)
if hasattr(func, '__qualname__'):
return func.__qualname__
# class methods, bound and unbound methods
f_self = getattr(func, '__self__', None) or getattr(func, 'im_self', None)
if f_self and hasattr(func, '__name__'):
f_class = f_self if isinstance(f_self, type) else f_self.__class__
else:
f_class = getattr(func, 'im_class', None)
if f_class and hasattr(func, '__name__'):
return '%s.%s' % (f_class.__name__, func.__name__)
# class or class instance
if hasattr(func, '__call__'):
# class
if hasattr(func, '__name__'):
return func.__name__
# instance of a class with a __call__ method
return func.__class__.__name__
raise TypeError('Unable to determine a name for %r -- maybe it is not a callable?' % func)
def obj_to_ref(obj):
"""
Returns the path to the given object.
:rtype: str
"""
try:
ref = '%s:%s' % (obj.__module__, get_callable_name(obj))
obj2 = ref_to_obj(ref)
if obj != obj2:
raise ValueError
except Exception:
raise ValueError('Cannot determine the reference to %r' % obj)
return ref
class TestObjToRef(object):
@pytest.mark.parametrize('input', [partial(DummyClass.meth)], ids=['partial/bound method'])
def test_no_ref_found(self, input):
exc = pytest.raises(ValueError, obj_to_ref, input)
assert 'Cannot determine the reference to ' in str(exc.value)
@pytest.mark.parametrize('input,expected', [
pytest.mark.skipif(sys.version_info[:2] == (3, 2), reason="Unbound methods can't be resolved on Python 3.2")(
(DummyClass.meth, 'tests.test_util:DummyClass.meth')
),
(DummyClass.classmeth, 'tests.test_util:DummyClass.classmeth'),
pytest.mark.skipif(sys.version_info < (3, 3), reason="Requires __qualname__ (Python 3.3+)")(
(DummyClass.InnerDummyClass.innerclassmeth, 'tests.test_util:DummyClass.InnerDummyClass.innerclassmeth')
),
pytest.mark.skipif(sys.version_info < (3, 3), reason="Requires __qualname__ (Python 3.3+)")(
(DummyClass.staticmeth, 'tests.test_util:DummyClass.staticmeth')
),
(timedelta, 'datetime:timedelta'),
], ids=['unbound method', 'class method', 'inner class method', 'static method', 'timedelta'])
def test_valid_refs(self, input, expected):
assert obj_to_ref(input) == expected
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment