Is there a way to debug a function that is defined dynamically in run time?
Or at least is there an easy way to find out where this function is produced?
Update to give more detail:
I used inspect module:
ipdb> inspect.getmodule(im.get_thumbnail_url)
Out[0]: <module 'django.utils.functional' from 'C:\java\python\Python25\Lib\site
-packages\django\utils\functional.pyc'>
ipdb> inspect.getsource(im.get_thumbnail_url)
Out[0]: ' def _curried(*moreargs, **morekwargs):\n return _curried_fun
c(*(args+moreargs), **dict(kwargs, **morekwargs))\n'
Here inspect shows that the get_thumbnail_url method of photos.models.Image class of pinax is produced by django.utils.functional.curry._curried function. But it still doesn’t show where the method is produced, namely where is _curried function called. This information is necessary to find out how get_thumbnail_url is implemented.
I can put pdb inside _curried function, but then it breaks lots of times there because this is a very frequently used function call. I need to have some distinguishing feature to use breakpoint condition.
Update about solution:
Thanks for all suggestions. I found out the solution. Let me explain how I found it. Maybe it will help other people:
First, I searched for ‘get_thumbnail_url’ term in pinax source code. No result.
Second, I searched for ‘thumbnail’ term in pinax source code. No useful result.
Lastly, I searched for ‘curry’ term in pinax source code. The following was one of several results:
def add_accessor_methods(self, *args, **kwargs):
for size in PhotoSizeCache().sizes.keys():
setattr(self, 'get_%s_size' % size,
curry(self._get_SIZE_size, size=size))
setattr(self, 'get_%s_photosize' % size,
curry(self._get_SIZE_photosize, size=size))
setattr(self, 'get_%s_url' % size,
curry(self._get_SIZE_url, size=size))
setattr(self, 'get_%s_filename' % size,
curry(self._get_SIZE_filename, size=size))
get_thumbnail_url method is produced by this call: curry(self._get_SIZE_url, size=size)).
But of course this is not a general solution method. If you can share alternative ways to find out where a dynamically defined function is actually produced, this would be of great use.
Edit:
The best general solution is written below by Jason Orendorff.
Given a function
f, in CPython you can printf.func_code.co_filenameandf.func_code.co_firstlinenoto get the file and first line number. This will not help if the function was created usingevalorexec.Tracebacks contain file and line information too.
If you
import disyou can usedis.dis(f)to see the CPython bytecodes; this might not be useful, but it might show some strings that help you find your way to the right place.Another thing to look at is PDB, the Python text-mode debugger. After an exception,
import pdb; pdb.pm()launches PDB. It’s primitive, but useful; typehelpfor a list of commands.whereshows the stack.EDIT: You mention this is a curried function. If it was created using
functools.partial, then it has a.funcattribute that refers to the underlying function.EDIT 2: The general way would be to set a breakpoint on
im.get_thumbnail_urland then immediately call it. Your breakpoint should hit right away. Then step until you reach the code you’re interested in.Since the curried function was, in this case, produced by code like:
another approach is to examine
f.func_closure, like this:The function closes on three variables: a tuple, a dict, and a function. Obviously the function is the one we’re interested in (but fyi these three cells correspond to the variables
args,kwargs, and_curried_functhat are defined in the enclosing functioncurrybut used by the closure_curried).