Steven D'Aprano steve+comp.lang.python at
Thu Aug 4 20:34:56 EDT 2011

Billy Mays wrote:

> Hey c.l.p.,
> I wrote a little python script that finds the file that a python module
> came from.  Does anyone see anything wrong with this script?

Yes -- the most screamingly obvious question has to be, why are you writing
directly to sys.stdout instead of just using print?

> #!/usr/bin/python

I believe the recommended, platform independent hash-bang line is

#!/usr/bin/which python

> import sys
> if __name__ == '__main__':
>      if len(sys.argv) > 1:
>          try:
>              m = __import__(sys.argv[1])

The major risk here is whether or not you trust the module enough to import
it and run arbitrary code. The alternative would be a lot more work: you
would have to duplicate the logic of the import statement, search the
PYTHONPATH, look for packages, inside zip files, etc. 

>              sys.stdout.write(m.__file__ + '\n')

Built-in modules don't have a __file__ attribute. The most obvious example:

>>> import builtins  # spelled __builtin__ in Python 2.x
>>> builtins.__file__
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute '__file__'

Also, __file__ is not always entirely honest. In Python 3, module.__file__
may report a .py file when it is actually loaded from a .pyc file, even if
the .py file doesn't exist. So if you care about the distinction
between .py, .pyc, .pyo etc. files, looking at __file__ alone will be

>          except ImportError:
>              sys.stderr.write("No such module '%s'\n" % sys.argv[1])

That's not a given -- it may be that the module exists, but importing fails
for some other reason. I would recommend not catching ImportError at all,
and just let the standard Python error handling print the traceback.
Especially for a tool aimed at programmers (who else would be interested in
PyWhich?), hiding useful diagnostic errors and replacing them with a
generic, and potentially wrong, message, is very bad.


More information about the Python-list mailing list