This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Glossary incorrectly describes a decorator as "merely syntactic sugar"
Type: Stage:
Components: Documentation Versions: Python 2.6
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: georg.brandl Nosy List: benjamin.peterson, georg.brandl, gpolo, kermode, terry.reedy
Priority: normal Keywords:

Created on 2008-12-31 18:59 by kermode, last changed 2022-04-11 14:56 by admin. This issue is now closed.

Messages (7)
msg78643 - (view) Author: Lenard Lindstrom (kermode) Date: 2008-12-31 18:59
http://www.python.org/doc/2.6/glossary.html

The decorator entry in the Python 2.6 documentation incorrectly
describes a decorator as "merely syntactic sugar". It is not, as this
example shows:

>>> def decorator(f):
	f.prev = globals()[f.__name__]
	return f

>>> func = 0
>>> def func():
	pass

>>> func = decorator(func)
>>> func.prev
<function func at 0x00C748F0>
>>> func = 0
>>> @decorator
def func():
	pass

>>> func.prev
0

This distinction could be useful in building multi-methods, for example.
msg78644 - (view) Author: Guilherme Polo (gpolo) * (Python committer) Date: 2008-12-31 19:22
Your example doesn't disprove the "merely syntactic sugar" found in the
documentation about the decorator syntax.

The results you are getting are based on when the decorator is applied.
msg78647 - (view) Author: Lenard Lindstrom (kermode) Date: 2008-12-31 19:44
It is distinct behavior. Without a decorator a new function is
immediately assigned to the identifier. Any previous reference is lost.
A decorator postpones assignment until the decorator returns. That
allows the decorator to access the previous object. I don't know of any
way to do the same thing with:

def foo():
   .....
foo = do_something(foo)

Here is part of a comp.lang.python thread discussing the possibility of
using a decorator for an overloaded function.

http://groups.google.com/group/comp.lang.python/browse_thread/thread/16a2e8b9d6705dfb/1cb0b358173daf06?lnk=gst&q=Lenard+Lindstrom+decorator#1cb0b358173daf06

Note that the decorator could create an overloaded function without any
extra variables. To do the equivalent in Python 2.3 a special attribute,
with a mangled name, was needed to store intermediate declarations.
msg78648 - (view) Author: Benjamin Peterson (benjamin.peterson) * (Python committer) Date: 2008-12-31 19:55
It is possible to "desugar" the exact behavior by creating the function
ones self.

Regardless, the usefulness this behavior is limited because it relys on
the decorator being in the same module as the function. It is also
fragile for nested functions.
msg78652 - (view) Author: Lenard Lindstrom (kermode) Date: 2008-12-31 21:17
The claim "merely" syntactic sugar implies that the inverse is also
true, the decorator expression:

@do_something
def foo():
    ....

can be replaced it with:

def foo():
    ....
foo = do_something(foo)

This is guaranteed if do_something is purely functional, but breaks if
do_something has side effects. The example was for illustration only. A
real application would likely access the parent frame. Whether or not
this is a questionable practice, it happens.

However, the issue is one of definitions. Is the phrase "merely
syntactic sugar" misleading? In this case it makes promises that may not
be kept.
msg78659 - (view) Author: Benjamin Peterson (benjamin.peterson) * (Python committer) Date: 2008-12-31 22:34
On Wed, Dec 31, 2008 at 3:17 PM, Lenard Lindstrom
<report@bugs.python.org> wrote:
>
> However, the issue is one of definitions. Is the phrase "merely
> syntactic sugar" misleading? In this case it makes promises that may not
> be kept.

It's not misleading because in 99.99% of all cases (and 100% of all
reasonable ones), they are the same. In fact, I would classify the
fact that the function hasn't been assigned yet a implementation
detail.
msg78884 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2009-01-02 21:50
Based on my reading of the pydev discussion, the doc correctly describes
the design intent.  If there is any bug, it is in the optimization of
skipping the apparently redundant first name binding.  I presume the
thinking was that since the decorator gets the function as an input,
there is no sensible need to access it again via its name.  A conforming
implementation should be free to not do this optimization, but to simply
make the easy and obvious translation.
History
Date User Action Args
2022-04-11 14:56:43adminsetgithub: 49043
2009-01-02 21:50:47terry.reedysetnosy: + terry.reedy
messages: + msg78884
2008-12-31 22:34:04benjamin.petersonsetmessages: + msg78659
2008-12-31 21:17:53kermodesetmessages: + msg78652
2008-12-31 19:55:43benjamin.petersonsetnosy: + benjamin.peterson
messages: + msg78648
2008-12-31 19:44:26kermodesetmessages: + msg78647
2008-12-31 19:22:08gpolosetstatus: open -> closed
nosy: + gpolo
resolution: not a bug
messages: + msg78644
2008-12-31 18:59:35kermodecreate