Proposed improved decorator syntax

barnesc at engr.orst.edu barnesc at engr.orst.edu
Thu Aug 5 20:54:56 EDT 2004


I'm revising my vote.

Thanks for the responses.

I vote against:

class foo:
    @synchronized
    @types("o,i,i")
    @author('Chris King')
    def introduceNewFeature(self, someArgument, anotherArgument):
        pass # whatever

Pros:
 - Allows arbitrary functions to be applied as decorators.

Cons:
 - Places decorator metadata before the function (in contrast with docstrings).
 - Hides function name.
 - @ symbols are ugly.
 - @ symbols are a particular hack for creating function metadata.
 - More such hacks may be needed in the future.
 - @ can be used to store metadata, but in a convoluted way:
   @name('Value') works, if function 'name' is defined (imports must be used
   for large projects); however the metadata name actually stored may be
   different than 'name' (ie no symmetry, no ease of use).
 - @ will be used for metadata, if no other solution is provided.

Recognize that we're *really* trying to create function metadata.  A more
flexible solution is to make a metadata dictionary be part of function and
class definitions.  Then 'decorator' simply becomes one name among many
different metadata names.

I vote for:

---------------------------------------------------------------------
Proposed Syntax
---------------------------------------------------------------------

class foo:
    def introduceNewFeature(self, someArgument, anotherArgument):
        .decorate = [synchronized]
        .accepts  = (int, int)
        .author   = 'Chris King'
        pass # whatever

Use introduceNewFeature.__meta__ to access the metadata dict.
The .accepts meta-datum calls isinstance() for each argument.
Use 'object' for arguments that can be any type.

Pros:
 - Readable.
 - No ugly @ symbols.
 - Metadata is placed after the function name.
 - .decorate is semantically superior to @.
 - Similar to existing Python syntax (equals sign and dots).
 - Allows metadata to be created and read (symmetrically, easily).
 - Allows arbitrary functions to be applied as decorators.
 - Code is ordered correctly (function declaration before docstring and
metadata).

Cons:
 - Name conflicts between builtin metadata names (eg 'decorate') and
   user metadata names (eg 'decorate').

Solutions to Name Conflicts:
 - Name conflicts are a small problem if the set of Python special
   metadata names is kept small and well documented (eg '.decorate'
   and '.accepts' can be documented as 'metadata keywords', to be
   avoided).
 - The paranoid can prefix metadata names with underscores.
 - Alternatively, .__decorate__ and .__accepts__ can be used.
 - Alternatively, {'decorate': [synchronized], 'accepts': (int, int)}
   can be used as the first line of metadata, which is interpreted
   as a 'Python special metadata dict'.

---------------------------------------------------------------------
Conclusion
---------------------------------------------------------------------

Either attack the full problem of metadata, or don't.

@ is a hack.  @ looks ugly.  @ is a particular solution for the general
problem domain of metadata.  @ is not clear to the uninitiated.  @ is
counter-intuitively present before the docstring.  @name('Value') is
can be used to store metadata, but lacks ease of use and symmetry.

Finally, @ does not appear to follow the tradition of Python.  It is a
very specialized extension statement, and at least deserves a descriptive
identifier in the code like 'decorate'.

Please don't stay silent on this issue.  Speak out!

We should really have a public vote.  I doubt the @ sign will be approved
if 99% of Python users oppose it.

 - Connelly



More information about the Python-list mailing list