Macros in Python?

Dominic oblivious at web.de
Fri Apr 11 14:19:39 EDT 2003


Beni Cherniavsky wrote:
> Dominic wrote on 2003-04-09:
> 
> 
>>(defmacro with-root-privs (() &body body)
>>   (let ((oldidsym (gensym)))
>>     `(let ((,oldidsym (geteuid)))
>>        (seteuid 0)
>>        (unwind-protect
>>	   (progn , at body)
>>	 (seteuid ,oldidsym)))))
>>
>>Is there an easy way to produce similar code
>>in Python which gurantees that certain things
>>happen around some code? (Maybe by using
>>generators?)
>>
> 
> To complete the list of solutions, there is an evil way to abstract
> try..finally that is not recommended due to it's unreadability to
> anybody that doesn't know the trick.  It also only works in CPython
> with reference counting that invokes __del__ immediately.
> 
> The basic idea was to use a for loop and a generator:
> 
> def with_root_privs():
>     oldid = geteuid()
>     seteuid(0)
>     yield None # dummy
>     seteuid(oldid)
> 
> for _ in with_root_privs:  # `_` is dummy
>     # Dohere whatever you wanted.  The generator will cause this to be
>     # executed exactly once, with pre- and post- code excuted...
> 
> The problem, of course is that the for loop's body can raise an
> exception, or exit the loop in other evil ways.  Luckily in CPython,
> exiting the loop immediately drops the only reference to the
> generator, so hooking it's __del__ would do the trick.  Writing it as
> an iterator class instead of a generator would be be ugly but we can
> only do it once, by a universal wrapper taking a naive generator and
> returning a safe one.  Google for "abstracting try..finally with
> generators" in c.l.py if you are interested.  Again, it's hard to
> recommend this hack.  Instead, consider pushing PEP 310 :-).

Actually I also considered using generators but I would never have
come by this idea to use ref-counting side effects to make
it work. ;-) This one is really great though it shouldn't be used...
Now I'll see what PEP 310 is all about.

Ciao,
  Dominic









More information about the Python-list mailing list