Search code examples
pythontrace

How to pass the self object to the trace.Trace.run() method?


In order to trace the execution of a program (exactly I want to follow the modules / classes / methods used when executing a particular line in a code), I try to use the trace module.

The line I want to explore is this:

trait = self._trait(name, 0)

so I changed this line in the code to:

#trait = self._trait(name, 0) import trace tracer = trace.trace(count=False, trace=True) tracer.run('trait = self._trait(name, 0)')

The problem is that in this case an exception is raised because self is not defined (since we pass a string in the tracer.run() ! method).

File "/usr/lib64/python3.6/trace.py", line 462, in runctx exec(cmd, globals, locals) File "<string>", line 1, in <module> NameError: name "self' is not defined

Is it possible to pass an object (as self) to the tracer.trace.run() method ?

Is there another way more suitable for this case to explore the path made during a python command?


Solution

  • You need to set the context for running the python statement to be traced using the runctx method. Here's an example, that says to put self into the tracer context as a local variable so that it can be referenced there:

    import trace
    
    class A:
      def f(self):
          self.g()
          print('f')
    
      def g(self):
          print('g')
    
      def h(self):
          # trace self.f()
          tracer = trace.Trace(count=False, trace=True)
          # define a local variable in the context named 'self'
          tracer.runctx('self.f()', locals={'self': self})
    
    a = A()
    a.h()
    

    The output:

     --- modulename: trc, funcname: f
    trc.py(5):       self.g()
     --- modulename: trc, funcname: g
    trc.py(9):       print('g')
    g
    trc.py(6):       print('f')
    f
     --- modulename: trace, funcname: _unsettrace
    trace.py(77):         sys.settrace(None)