2

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
Peter
  • 401
  • 1
  • 5
  • 17

0 Answers0