PyWhich
Steven D'Aprano
steve+comp.lang.python at pearwood.info
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
inadequate.
> 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.
--
Steven
More information about the Python-list
mailing list