
Peter Norvig suggested an idea to me over lunch: a "default decorator". This would be something you could set once per module and it would be invoked for each function definition in the same way as a decorator is invoked, before any explicit decorators. His use case was something that wraps every function that uses argument annotations with something that interprets those annotations in a certain way and enforces that interpretation. It would save having to explicitly annotate every function or method that way. Thoughts? I suggested that a metaclass could do this for methods, but that of course leaves plain functions in the lurch. -- --Guido van Rossum (home page: http://www.python.org/~guido/)

On Jan 16, 2008 4:31 PM, Guido van Rossum <guido@python.org> wrote:
Do we want something like a global decorator, or more something like __build_class__ for the 'def' statement (although a quick attempt at replacing __build_class__ didn't work for me)? I personally prefer the latter as that is the more powerful solution between the two. Plus I don't see the need for a global decorator coming up often enough to warrant making it simpler. -Brett

On Jan 16, 2008 4:58 PM, Brett Cannon <brett@python.org> wrote:
Wasn't __build_class__ only in an early version of PEP 3115?
The use case might come up a lot more if people take the argument annotations idea and run with it. They might want to add lots of annotations to lots of functions, and then have one convenient way to ensure all those functions are wrapped by something that actually uses the annotations for something (e.g. adaptation or type checking). -- --Guido van Rossum (home page: http://www.python.org/~guido/)

Guido van Rossum wrote:
Wasn't __build_class__ only in an early version of PEP 3115?
It's still in builtins as builtins.__build_class__ and it's used by ceval for LOAD_BUILD_CLASS.
Right, the use cases will pop up once people start to use annotations a lot. But does the use case really satisfy a new hook? Isn't a meta class factory and a simple function enough? Christian

Guido van Rossum wrote:
Is it really required? As it is trivial to write a meta class to decorator all members of a class, it is also trivial to write a function which accepts a module name and decorate all functions in the module. def decorate_functions(decorator, modname): function = type(decorate_functions) namespace = sys.modules[modname].__dict__ for name, obj in namespace.items(): if isinstance(obj, function): namespace[name] = decorator(obj) decorate_functions(somefunc, __name__) Does a default decorator also decorate nested functions (function with functions)? And does it also decorate class members or function created with exec()? What about lambda? Christian

__decor__= functools.partial( "when?" ) __lambdadec__= functools.partial( "say when." ) __classdec__= functools.partial( "now." ) __classmethoddec__= functools.partial( "ooh. too much." ) or: from functools import partial __decor__= funcutils.ModuleDec( partial( "where?" ), lambdadec= partial( "there." ), classmethdec= partial( "never." ) )

On Jan 16, 2008 5:13 PM, Aaron Brady <castironpi@comcast.net> wrote:
Aaron, if you aren't capable of expression your thoughts in English, you might as well not bother to post. -- --Guido van Rossum (home page: http://www.python.org/~guido/)

+1 from me. But I'm just a ignorant python end-user :-) I imagine it would probably end up being used like the __metaclass__ module hook is now. On Jan 16, 2008 6:05 PM, Christian Heimes <lists@cheimes.de> wrote:
The __metaclass__ hook currently changes the metaclass for nested classes, the decorator hook could follow the same semantics:
Lambdas don't currently support parameter annotations, so they should be left out. -- ===== --Ryan E. Freckleton

On Jan 16, 2008 10:33 PM, Ryan Freckleton <ryan.freckleton@gmail.com> wrote:
One problem is that you can override a module level __metaclass__ with a class level __metaclass__, but I dont see how i could express this for default decorators. How would i be able to say "all functions but this one"? In that case, the default decorator is useless. Lucio.

On Thu, Jan 17, 2008 at 02:05:40AM +0100, Christian Heimes wrote:
it is also trivial to write a function which accepts a module name
A module object, perhaps? Modules are first-class citizens, no need to fetch them by name. Or have I missed something? Oleg. -- Oleg Broytmann http://phd.pp.ru/ phd@phd.pp.ru Programmers don't die, they just GOSUB without RETURN.

python-ideas@python.org On 17 Jan 2008, at 01:05, Christian Heimes wrote:
This doesn't work as decorators don't usually commute. If the module contains a function: @foo def bar(...) decorate_functions will change it to: @somefunc @foo def bar(...) Whereas the desired result is: @foo @somefunc def bar(...) -- Arnaud

On Jan 16, 2008, at 4:31 PM, Guido van Rossum wrote:
Great idea. +1 on a "default decorator". Like the global __metaclass__, I'd hope that it could apply to functions nested in classes, but not functions nested in functions. A lot of the same reasons for __metaclass__ apply to __decorator__: "The potential uses for metaclasses are boundless. Some ideas that have been explored including logging, interface checking, automatic delegation, automatic property creation, proxies, frameworks, and automatic resource locking/synchronization." http://docs.python.org/ref/metaclasses.html -Tony

On 1/16/08, Guido van Rossum <guido@python.org> wrote:
I would prefer that it be easier to control module creation in general. The decorator does meet his use case (and logging/tracing/registration), but there are varieties that would work better if the decorator were applied after any explicit decorators. (OTOH, doing that all the time raises the problem about whether decorators commute.) There are already questions about whether it should apply to nested functions or lambdas. You can just settle those questions by fiat and meet 90% of the need, but letting the module control it seems cleaner (and also allows other extensions, such as alternate module dict representations). As to how module creation should be controlled -- that is a bit hairier. My strawman is a __moduleclass__ analogous to __metaclass__. myfile.py: __moduleclass__=altmod.mod1 would be the moral equivalent of (some other file) running import sys import altmod sys.modules["myfile"]=altmod.mod1() exec myfile in sys.modules["myfile"] -jJ

On Thu, Jan 17, 2008, Jim Jewett wrote:
I would prefer that it be easier to control module creation in general.
Right. I haven't been paying much attention, but can the post-import hook play nicely with this? -- Aahz (aahz@pythoncraft.com) <*> http://www.pythoncraft.com/ "All problems in computer science can be solved by another level of indirection." --Butler Lampson

Quick response: this was already discussed, the requirement is for this to happen to *any* def or lambda *before* applying decorators and *regardless* of where/how they are nested (e.g. methods, nested functions, etc.). --Guido On Jan 17, 2008 7:16 AM, Jim Jewett <jimjjewett@gmail.com> wrote:
-- --Guido van Rossum (home page: http://www.python.org/~guido/)

On Jan 16, 2008 4:31 PM, Guido van Rossum <guido@python.org> wrote:
Do we want something like a global decorator, or more something like __build_class__ for the 'def' statement (although a quick attempt at replacing __build_class__ didn't work for me)? I personally prefer the latter as that is the more powerful solution between the two. Plus I don't see the need for a global decorator coming up often enough to warrant making it simpler. -Brett

On Jan 16, 2008 4:58 PM, Brett Cannon <brett@python.org> wrote:
Wasn't __build_class__ only in an early version of PEP 3115?
The use case might come up a lot more if people take the argument annotations idea and run with it. They might want to add lots of annotations to lots of functions, and then have one convenient way to ensure all those functions are wrapped by something that actually uses the annotations for something (e.g. adaptation or type checking). -- --Guido van Rossum (home page: http://www.python.org/~guido/)

Guido van Rossum wrote:
Wasn't __build_class__ only in an early version of PEP 3115?
It's still in builtins as builtins.__build_class__ and it's used by ceval for LOAD_BUILD_CLASS.
Right, the use cases will pop up once people start to use annotations a lot. But does the use case really satisfy a new hook? Isn't a meta class factory and a simple function enough? Christian

Guido van Rossum wrote:
Is it really required? As it is trivial to write a meta class to decorator all members of a class, it is also trivial to write a function which accepts a module name and decorate all functions in the module. def decorate_functions(decorator, modname): function = type(decorate_functions) namespace = sys.modules[modname].__dict__ for name, obj in namespace.items(): if isinstance(obj, function): namespace[name] = decorator(obj) decorate_functions(somefunc, __name__) Does a default decorator also decorate nested functions (function with functions)? And does it also decorate class members or function created with exec()? What about lambda? Christian

__decor__= functools.partial( "when?" ) __lambdadec__= functools.partial( "say when." ) __classdec__= functools.partial( "now." ) __classmethoddec__= functools.partial( "ooh. too much." ) or: from functools import partial __decor__= funcutils.ModuleDec( partial( "where?" ), lambdadec= partial( "there." ), classmethdec= partial( "never." ) )

On Jan 16, 2008 5:13 PM, Aaron Brady <castironpi@comcast.net> wrote:
Aaron, if you aren't capable of expression your thoughts in English, you might as well not bother to post. -- --Guido van Rossum (home page: http://www.python.org/~guido/)

+1 from me. But I'm just a ignorant python end-user :-) I imagine it would probably end up being used like the __metaclass__ module hook is now. On Jan 16, 2008 6:05 PM, Christian Heimes <lists@cheimes.de> wrote:
The __metaclass__ hook currently changes the metaclass for nested classes, the decorator hook could follow the same semantics:
Lambdas don't currently support parameter annotations, so they should be left out. -- ===== --Ryan E. Freckleton

On Jan 16, 2008 10:33 PM, Ryan Freckleton <ryan.freckleton@gmail.com> wrote:
One problem is that you can override a module level __metaclass__ with a class level __metaclass__, but I dont see how i could express this for default decorators. How would i be able to say "all functions but this one"? In that case, the default decorator is useless. Lucio.

On Thu, Jan 17, 2008 at 02:05:40AM +0100, Christian Heimes wrote:
it is also trivial to write a function which accepts a module name
A module object, perhaps? Modules are first-class citizens, no need to fetch them by name. Or have I missed something? Oleg. -- Oleg Broytmann http://phd.pp.ru/ phd@phd.pp.ru Programmers don't die, they just GOSUB without RETURN.

python-ideas@python.org On 17 Jan 2008, at 01:05, Christian Heimes wrote:
This doesn't work as decorators don't usually commute. If the module contains a function: @foo def bar(...) decorate_functions will change it to: @somefunc @foo def bar(...) Whereas the desired result is: @foo @somefunc def bar(...) -- Arnaud

On Jan 16, 2008, at 4:31 PM, Guido van Rossum wrote:
Great idea. +1 on a "default decorator". Like the global __metaclass__, I'd hope that it could apply to functions nested in classes, but not functions nested in functions. A lot of the same reasons for __metaclass__ apply to __decorator__: "The potential uses for metaclasses are boundless. Some ideas that have been explored including logging, interface checking, automatic delegation, automatic property creation, proxies, frameworks, and automatic resource locking/synchronization." http://docs.python.org/ref/metaclasses.html -Tony

On 1/16/08, Guido van Rossum <guido@python.org> wrote:
I would prefer that it be easier to control module creation in general. The decorator does meet his use case (and logging/tracing/registration), but there are varieties that would work better if the decorator were applied after any explicit decorators. (OTOH, doing that all the time raises the problem about whether decorators commute.) There are already questions about whether it should apply to nested functions or lambdas. You can just settle those questions by fiat and meet 90% of the need, but letting the module control it seems cleaner (and also allows other extensions, such as alternate module dict representations). As to how module creation should be controlled -- that is a bit hairier. My strawman is a __moduleclass__ analogous to __metaclass__. myfile.py: __moduleclass__=altmod.mod1 would be the moral equivalent of (some other file) running import sys import altmod sys.modules["myfile"]=altmod.mod1() exec myfile in sys.modules["myfile"] -jJ

On Thu, Jan 17, 2008, Jim Jewett wrote:
I would prefer that it be easier to control module creation in general.
Right. I haven't been paying much attention, but can the post-import hook play nicely with this? -- Aahz (aahz@pythoncraft.com) <*> http://www.pythoncraft.com/ "All problems in computer science can be solved by another level of indirection." --Butler Lampson

Quick response: this was already discussed, the requirement is for this to happen to *any* def or lambda *before* applying decorators and *regardless* of where/how they are nested (e.g. methods, nested functions, etc.). --Guido On Jan 17, 2008 7:16 AM, Jim Jewett <jimjjewett@gmail.com> wrote:
-- --Guido van Rossum (home page: http://www.python.org/~guido/)
participants (11)
-
Aahz
-
Aaron Brady
-
Arnaud Delobelle
-
Brett Cannon
-
Christian Heimes
-
Guido van Rossum
-
Jim Jewett
-
Lucio Torre
-
Oleg Broytmann
-
Ryan Freckleton
-
Tony Lownds