Search code examples
djangotrace

Trace method resolution order at runtime


I am working on some code (not mine) and I try to instand it.

There 16 classes in the inheritance tree.

Here area the class according to inspect.getmro(self.__class__)

  • foo_barcheck.views.barcheck.AdminListActionView
  • foo_barcheck.views.barcheck.ListActionMixin
  • djangotools.utils.urlresolverutils.UrlMixin
  • foo.views.ListActionView
  • foo.views.ContextMixin
  • foo.views.fooMixin
  • djangotools.views.ListActionView
  • djangotools.views.ListViewMixin
  • django.views.generic.list.MultipleObjectMixin
  • django.views.generic.edit.FormMixin
  • djangotools.views.DTMixin
  • django.views.generic.base.TemplateView
  • django.views.generic.base.TemplateResponseMixin
  • django.views.generic.base.ContextMixin
  • django.views.generic.base.View
  • object

I want to trace what happens if I call self.do_magic().

I want to see all do_magic() calls of these 16 classes.

The ideal solution would look like this:

result_of_do_magic, list_of_do_magic_methods = trace_method_calls(self.do_magic)

I have no clue how to implement trace_method_calls(). It should execute the code and trace the method calls at runtime.

Is there a tracing guru which knows how to do this?

AFAIK this needs to be done at runtime, since I don't know if all methods calls the do_magic() of the parents via super().

Update

I don't want to modify the code to be able to trace it. I guess this should be possible, since the mocking library can do comparable magic.


Solution

  • If I understand correctly, I can see 2 solutions here.

    1) [Brute-ish and relatively easy] Find all occurrences of "do_magic" in your code and wrap it with decorator like:

    def trace_this(fn):
        def wrapped(*args, **kwargs):
            print("do_magic is called!")
            result = fn(*args, **kwargs)
            print("Result is:{0}".format(result))
            return result
    return wrapped
    ...
    @trace_this
    def do_magic():
        ...
    

    2) Run django as:

    python -m trace -t manage.py runserver 127.0.0.1:8000 --noreload > trace.txt
    

    and all invoked code would be in trace.txt that you can then parse/analyze with tools you prefer.