
"Phillip J. Eby" <pje@telecommunity.com> writes:
At 01:26 PM 6/24/04 -0400, David Abrahams wrote:
Anthony Baxter <anthony@interlink.com.au> writes:
So, let the floodgates open. Remember, we _can_ change this any time up until 2.4b1, if there's a decision that the chosen form sucks. :-)
Here's thinking in a different direction altogether:
No special syntax
Instead, expose enough functionality in standard library functions that an appropriately-written pure-python "decorate" function can do it.
decorate(staticmethod, my_decorator) def f(x): whatever()
Since function definitions are executable statements, it should in principle be possible to arrange something that allows one to hook the execution of that statement. Perhaps it's already doable with the debugger hook?
Hmmm. You probably *could* create such a function in CPython, maybe even as far back as 2.1 (since all it needs is sys._getframe and the tracing hook), but it wouldn't be portable to Jython.
And, boy, would it be a sick and twisted piece of code.
What you wrote doesn't look all *that* awful.
You'd need to do something like keep a copy of the locals and on each "new line" event from the trace hook, you'd need to both call the old trace hook (so that debugging could still take place) and check to see if the locals had a new function object. As soon as the function object appeared, you could do your dirty work (after first restoring the *old* value bound to that name, so the decorators would have access to the previous binding of the name).
I'm perfectly happy for this decorate function to work on the very next name binding; I don't think it's reasonable to expect to be able to do anything else between it and the function definition.
About the only bit you couldn't do in pure Python would be decorating a function defined in a nested scope, because "fast locals" aren't accessible from pure Python.
You're beyond my expertise here.
But for module-level functions and methods in classes, this might actually work. Heck, I'm rather tempted to try to write it and see if it does. At worst, it might be a fun way to learn the ins and outs of sys.settrace().
<snip>
Anyway, it works with CPython 2.2. Caveat: do *not* use listcomps or any other assignment statements between your 'decorate()' invocation and the function definition, or the decorators will be applied to the bound-to variable!
Personally, I think the 'decorate()' function is probably actually not that useful, compared to making specialized decoration functions like, say:
classmethod_follows() def foo(klass, x, y, z): # ...
Ick!
Only with better names. :) Also, using this approach means you can do something like:
[classmethod_follows()]
Ick in brackets ;-> ! -- Dave Abrahams Boost Consulting http://www.boost-consulting.com