Finding the name of an object's source file

Peter Otten __peter__ at web.de
Tue Jun 6 06:20:57 EDT 2017


Friedrich Rentsch wrote:

> Hi all,
> 
> Developing a project, I have portions that work and should be assembled
> into a final program. Some parts don't interconnect when they should,
> because of my lack of rigor in managing versions. So in order to get on,
> I should next tidy up the mess and the way I can think of to do it is to
> read out the source file names of all of a working component's elements,
> then delete unused files and consolidate redundancy.
> 
> So, the task would be to find source file names. inspect.getsource ()
> knows which file to take the source from, but as far as I can tell, none
> of its methods reveals that name, if called on a command line (>>>
> inspect.(get source file name) ()). Object.__module__ works.
> Module.__file__ works, but Object.__module__.__file__ doesn't, because
> Object.__module__ is only a string.
> 
> After one hour of googling, I believe inspect() is used mainly at
> runtime (introspection?) for tracing purposes. An alternative to
> inspect() has not come up. I guess I could grep inspect.(getsource ()),
> but that doesn't feel right. There's probably a simpler way. Any
> suggestions?

What you have is a function that shows a function's source code 
(inspect.getsource) and a function that as part of its implementation does 
what you need (also inspect.getsource, incidentally). So why not combine the 
two to find the interesting part?

>>> import inspect
>>> print(inspect.getsource(inspect.getsource))
def getsource(object):
...
    lines, lnum = getsourcelines(object)
    return ''.join(lines)

Next attempt:

>>> print(inspect.getsource(inspect.getsourcelines))
def getsourcelines(object):
    ...
    lines, lnum = findsource(object)

    if ismodule(object): return lines, 0
    else: return getblock(lines[lnum:]), lnum + 1

findsource? Looks like we are getting closer.

>>> print(inspect.getsource(inspect.findsource))              
def findsource(object):
    """Return the entire source file and starting line number for an object.

    The argument may be a module, class, method, function, traceback, frame,
    or code object.  The source code is returned as a list of all the lines
    in the file and the line number indexes a line in that list.  An OSError
    is raised if the source code cannot be retrieved."""

    file = getsourcefile(object)
    ...

Heureka:

>>> import os
>>> inspect.getsourcefile(os.path.split)
'/usr/lib/python3.4/posixpath.py'

And so much more fun than scanning the documentation :)




More information about the Python-list mailing list