Fix is_method_of (cf #310), add regression test case

This commit is contained in:
enkore 2016-01-28 20:34:53 +01:00
parent cfe9ec4c43
commit 739c595ef0
2 changed files with 30 additions and 1 deletions

View File

@ -10,8 +10,12 @@ from i3pystatus.core.command import run_through_shell
def is_method_of(method, object):
"""Decide whether ``method`` is contained within the MRO of ``object``."""
if not callable(method) or not hasattr(method, "__name__"):
return False
if inspect.ismethod(method):
return method.__self__ is object
for cls in inspect.getmro(object.__class__):
if method in cls.__dict__.values():
if cls.__dict__.get(method.__name__, None) is method:
return True
return False

View File

@ -4,6 +4,7 @@ from unittest.mock import MagicMock
import pytest
from i3pystatus import IntervalModule
from i3pystatus.core.modules import is_method_of
left_click = 1
right_click = 3
@ -120,3 +121,27 @@ def test_callback_handler_function():
dut = TestClicks()
dut.on_click(scroll_up)
callback_mock.callback.assert_called_once_with("upscroll")
def test_is_method_of():
class TestClass:
def method(self):
pass
# member assigned functions cannot be distinguished in unbound state
# by principle from methods, since both are functions. However, in
# most cases it can still be shown correctly that a member assigned
# function is not a method, since the member name and function name
# are different (in this example the assigned member is 'assigned_function',
# while the name of the function is 'len', hence is_method_of can say for
# sure that assigned_function isn't a method
assigned_function = len
member = 1234
string_member = "abcd"
object = TestClass()
for source_object in [object, TestClass]:
assert is_method_of(source_object.method, object)
assert not is_method_of(source_object.assigned_function, object)
assert not is_method_of(source_object.member, object)
assert not is_method_of(source_object.string_member, object)