perl-like -M option

Erwin S. Andreasen erw at dde.dk
Mon Feb 14 16:05:41 CET 2000


perl has a useful -M option that lets you import a module on the command
line. E.g. perl -MLWP::Simple -e 'print get "http://www.python.org"' will
import the LWP::Simple module, then run the get function from that (which
gets a documented point to by an URL) and prints the result.

I personally find that handy so I've implemented something similar in
Python. If you specify:

-Mmodulename              It does a "from modulename import *"
-Mmodulename:foo          It does a "from modulename import foo"
-Mmodulename:             It does a "import foo"

(accidentally, -Mm1,m2,m3: works too)

Before:

./python -c 'import urllib, string;\
  print string.join(urllib.urlopen("http://berta").readlines(), "")'

After:

./python -Murllib -Mstring -c 
  'print join(urlopen("http://berta").readlines(), "")'


It feels a bit more readable in such oneliners. More usefully, this could be
used to invoke some modules that make magic stuff happen to an existing
program, without having to edit the program. E.g. consider this (there may
be some obvious ways of manipulating the dictionaries easier, but I've only
written some 500 lines of various Python code so far :) )

Trace.py:
---------
import sys

trace = [ 'open' ]
main = __import__('__main__')

class Wrapper:
  def __init__(self,name,what):
    self.name, self.what = name, what
  def __call__(self,*args):
    print ">>", self.name, str(args), " = ",
    try:
      result = apply(self.what, args)
    except Exception, e:
      print e
      raise e, None, sys.exc_info()[2]
    print str(result)
    return result

for x in trace:
# Not sure if this is the most optimal way of doing it :)
  main.__dict__[x] = Wrapper(x, __builtins__[x])



If you have a file like:
open("/etc/passwd", "r")
open("/etc/passwd2", "r")

and run: python -MTrace: thatfile

you would get something like:

>> open ('/etc/passwd', 'r')  =  <open file '/etc/passwd', mode 'r' at 80df298>
>> open ('/etc/passwdd', 'r')  =  [Errno 2] No such file or directory: '/etc/passwdd'
Traceback (innermost last):
[...]

Of course that will only affect the main module... but I suppose that you
could override importing too, and add some code to add the tracing to the
imported modules.

Anyway, that's the general idea, that you can easily import modules on code
you execute on the command line with -c, and that you can import modules
that do something extra to the program executed.

Does that seem useful? The patch against 1.5.2 is at
http://www.andreasen.org/misc/pypatch -- it's currently not in a state that
complies with the standards for patches as I can see them on www.python.org,
just a tentative idea.


-- 
==============================================================================
Erwin Andreasen   Herlev, Denmark <erw at dde.dk>          UNIX System Programmer
<URL:http://www.andreasen.org>              <*>         (not speaking for) DDE
==============================================================================



More information about the Python-list mailing list