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