I want to get the class which contains a given method. Unfortunately, this great answer does not work in my context. How can I extend it to work?
Specifically, I am running the below code through pytest --import-mode=importlib
. The problem seems to be that inspect.getmodule(meth)
returns None
when using flag --import-mode=importlib
.
import functools
import inspect
from unittest import TestCase
class TestClassThatDefinedMethod(TestCase):
def test_get_class_that_defined_method(self):
cls = get_class_that_defined_method(ClassWithFunctions.f)
self.assertIs(cls, ClassWithFunctions)
# AssertionError: None is not <class 'a_test.ClassWithFunctions'>
class ClassWithFunctions:
def f(self):
pass
def get_class_that_defined_method(meth):
# Taken from https://stackoverflow.com/a/25959545/2761174
if isinstance(meth, functools.partial):
return get_class_that_defined_method(meth.func)
if inspect.ismethod(meth) or (inspect.isbuiltin(meth) and getattr(meth, '__self__', None) is not None and getattr(meth.__self__, '__class__', None)):
for cls in inspect.getmro(meth.__self__.__class__):
if meth.__name__ in cls.__dict__:
return cls
meth = getattr(meth, '__func__', meth) # fallback to __qualname__ parsing
if inspect.isfunction(meth):
cls = getattr(inspect.getmodule(meth),
meth.__qualname__.split('.<locals>', 1)[0].rsplit('.', 1)[0],
None)
if isinstance(cls, type):
return cls
return getattr(meth, '__objclass__', None) # handle special descriptor objects