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)
python类get_method_self()的实例源码
def is_same_callback(callback1, callback2, strict=True):
"""Returns if the two callbacks are the same."""
if callback1 is callback2:
# This happens when plain methods are given (or static/non-bound
# methods).
return True
if callback1 == callback2:
if not strict:
return True
# Two bound methods are equal if functions themselves are equal and
# objects they are applied to are equal. This means that a bound
# method could be the same bound method on another object if the
# objects have __eq__ methods that return true (when in fact it is a
# different bound method). Python u so crazy!
try:
self1 = six.get_method_self(callback1)
self2 = six.get_method_self(callback2)
return self1 is self2
except AttributeError: # nosec
pass
return False
def is_same_callback(callback1, callback2, strict=True):
"""Returns if the two callbacks are the same."""
if callback1 is callback2:
# This happens when plain methods are given (or static/non-bound
# methods).
return True
if callback1 == callback2:
if not strict:
return True
# Two bound methods are equal if functions themselves are equal and
# objects they are applied to are equal. This means that a bound
# method could be the same bound method on another object if the
# objects have __eq__ methods that return true (when in fact it is a
# different bound method). Python u so crazy!
try:
self1 = six.get_method_self(callback1)
self2 = six.get_method_self(callback2)
return self1 is self2
except AttributeError: # nosec
pass
return False
def call_unlogged(method, *args, **kwargs):
"""Calls the original method without logging when ``logged`` is applied.
In case you pass in an ordinary method that was not decorated, it will work as usual.
Args:
method: The method object from the object.
*args: Args to pass to the method.
**kwargs: Keyword arguments to pass to the method.
Returns:
Whatever that method returns.
"""
try:
f = method.original_function
except AttributeError:
f = get_method_function(method)
return f(get_method_self(method), *args, **kwargs)
def get_class_name(obj, fully_qualified=True):
"""Get class name for object.
If object is a type, returns name of the type. If object is a bound
method or a class method, returns its ``self`` object's class name.
If object is an instance of class, returns instance's class name.
Else, name of the type of the object is returned. If fully_qualified
is True, returns fully qualified name of the type. For builtin types,
just name is returned. TypeError is raised if can't get class name from
object.
"""
if inspect.isfunction(obj):
raise TypeError("Can't get class name.")
if inspect.ismethod(obj):
obj = get_method_self(obj)
if not isinstance(obj, six.class_types):
obj = type(obj)
try:
built_in = obj.__module__ in _BUILTIN_MODULES
except AttributeError: # nosec
pass
else:
if built_in:
return obj.__name__
if fully_qualified and hasattr(obj, '__module__'):
return '%s.%s' % (obj.__module__, obj.__name__)
else:
return obj.__name__
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 is_bound_method(method):
"""Returns if the given method is bound to an object."""
return get_method_self(method) is not None
def get_class_name(obj, fully_qualified=True):
"""Get class name for object.
If object is a type, returns name of the type. If object is a bound
method or a class method, returns its ``self`` object's class name.
If object is an instance of class, returns instance's class name.
Else, name of the type of the object is returned. If fully_qualified
is True, returns fully qualified name of the type. For builtin types,
just name is returned. TypeError is raised if can't get class name from
object.
"""
if inspect.isfunction(obj):
raise TypeError("Can't get class name.")
if inspect.ismethod(obj):
obj = get_method_self(obj)
if not isinstance(obj, six.class_types):
obj = type(obj)
try:
built_in = obj.__module__ in _BUILTIN_MODULES
except AttributeError: # nosec
pass
else:
if built_in:
return obj.__name__
if fully_qualified and hasattr(obj, '__module__'):
return '%s.%s' % (obj.__module__, obj.__name__)
else:
return obj.__name__
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)
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 is_bound_method(method):
"""Returns if the given method is bound to an object."""
return get_method_self(method) is not None
def get_bound_method(obj, method_name):
"""Get a bound method of the given object by name.
Args:
obj: Object on which to look up the method.
method_name: Name of the method to retrieve.
Returns:
Bound method, or ``None`` if the method does not exist on
the object.
Raises:
AttributeError: The method exists, but it isn't
bound (most likely a class was passed, rather than
an instance of that class).
"""
method = getattr(obj, method_name, None)
if method is not None:
# NOTE(kgriffs): Ensure it is a bound method
if six.get_method_self(method) is None:
# NOTE(kgriffs): In Python 3 this code is unreachable
# because the above will raise AttributeError on its
# own.
msg = '{0} must be a bound method'.format(method)
raise AttributeError(msg)
return method
def test_get_method_self():
class X(object):
def m(self):
pass
x = X()
assert six.get_method_self(x.m) is x
py.test.raises(AttributeError, six.get_method_self, 42)
def __init__(self, method):
super(CallMonitor, self).__init__(six.get_method_self(method), method)
def replaced(method, replacement, on=None):
"""A context manager which replaces the method passed in as `method` with the callable
in `replacement` for the duration of the managed context.
.. code-block:: python
class SomethingElse(object):
def foo(self, n, y='yyy'):
assert None, 'This should never be reached in this test'
s = SomethingElse()
def replacement(n, y=None):
return y
with replaced(s.foo, replacement):
assert s.foo(1, y='a') == 'a'
assert s.foo(2) == None
assert s.foo(2) == 'yyy'
"""
StubClass.signatures_match(method, replacement, ignore_self=True)
is_unbound_method = six.PY2 and inspect.ismethod(method) and not method.im_self
if (not inspect.ismethod(method) or is_unbound_method) and not on:
raise ValueError('You have to supply a on= when stubbing an unbound method')
target = on or six.get_method_self(method)
if inspect.isfunction(method) or inspect.isbuiltin(method):
method_name = method.__name__
else:
method_name = six.get_method_function(method).__name__
saved_method = getattr(target, method_name)
try:
setattr(target, method_name, replacement)
yield
finally:
setattr(target, method_name, saved_method)
def is_bound_method(ob):
return inspect.ismethod(ob) and six.get_method_self(ob) is not None
def __set_parent(self, parent):
if ismethod(parent):
self._parent = six.get_method_self(parent)
else:
self._parent = parent
def handle_security(controller, im_self=None):
""" Checks the security of a controller. """
if controller._pecan.get('secured', False):
check_permissions = controller._pecan['check_permissions']
if isinstance(check_permissions, six.string_types):
check_permissions = getattr(
im_self or six.get_method_self(controller),
check_permissions
)
if not check_permissions():
raise exc.HTTPUnauthorized
def test_get_method_self():
class X(object):
def m(self):
pass
x = X()
assert six.get_method_self(x.m) is x
py.test.raises(AttributeError, six.get_method_self, 42)
def _find_method(obj, func):
if obj:
try:
func_self = six.get_method_self(func)
except AttributeError: # func has no __self__
pass
else:
if func_self is obj:
return six.get_method_function(func).__name__
raise ValueError("Function %s is not a method of: %s" % (func, obj))
def get_bound_method(obj, method_name):
"""Get a bound method of the given object by name.
Args:
obj: Object on which to look up the method.
method_name: Name of the method to retrieve.
Returns:
Bound method, or ``None`` if the method does not exist on
the object.
Raises:
AttributeError: The method exists, but it isn't
bound (most likely a class was passed, rather than
an instance of that class).
"""
method = getattr(obj, method_name, None)
if method is not None:
# NOTE(kgriffs): Ensure it is a bound method
if six.get_method_self(method) is None:
# NOTE(kgriffs): In Python 3 this code is unreachable
# because the above will raise AttributeError on its
# own.
msg = '{0} must be a bound method'.format(method)
raise AttributeError(msg)
return method
def _reject_self_from_args(func, args):
if len(args) == 0:
return args
try:
self = six.get_method_self(func)
except Exception:
return args
if args[0] == self:
return args[1:]
else:
return args
def test_get_method_self():
class X(object):
def m(self):
pass
x = X()
assert six.get_method_self(x.m) is x
py.test.raises(AttributeError, six.get_method_self, 42)
def pytest_runtest_teardown(item, nextitem):
"""Pytest hook to dispatch destructive scenarios."""
do_revert = True
# Prevent reverting after skipped tests
if getattr(item, SKIPPED, False):
do_revert = False
# Revert only destructive tests
if not item.get_marker(DESTRUCTIVE):
do_revert = False
snapshot_name = item.session.config.option.snapshot_name
# Prevent reverting if no snapshot_name passed
if snapshot_name is None:
do_revert = False
if do_revert:
destructor = item._request.getfixturevalue('os_faults_client')
# reject finalizers of all fixture scopes
for finalizers in item.session._setupstate._finalizers.values():
for finalizer in finalizers:
# There are finalizers in the form of lambda function without
# name. That looks as internal pytest specifics. We should skip
# them.
try:
fixture_def = six.get_method_self(finalizer)
except AttributeError:
continue
if not hasattr(fixture_def.func, INDESTRUCTIBLE):
LOG.debug('Clear {} finalizers'.format(fixture_def))
fixture_def._finalizer[:] = []
# Clear fixture cached result to force fixture with any
# scope to restart in next test.
if hasattr(fixture_def, "cached_result"):
LOG.debug('Clear {} cache'.format(fixture_def))
del fixture_def.cached_result
outcome = yield
# Prevent reverting after last test
if nextitem is None or item.session.shouldstop:
do_revert = False
# Prevent reverting after KeyboardInterrupt
if outcome.excinfo is not None and outcome.excinfo[0] is KeyboardInterrupt:
do_revert = False
if do_revert and destructor:
revert_environment(destructor, snapshot_name)
time.sleep(item.session.config.option.revert_timeout * 60)