r1279 (breaks third-party decorators)

0 views
Skip to first unread message

Simon Belak

unread,
Apr 27, 2006, 6:42:54 PM4/27/06
to turbogea...@googlegroups.com
Hi,

I'm going to make everyone's life miserable again. ;)

In r1279 I added support for "alternative" decorator syntax as used by
PEAK to lessen the anguish of people still on Python 2.3. This
unfortunately requires a bit different application of decorator() function.

Before:

def foo(a):
def entagle(func)
def caller(func, *args, **kw):
func(*args, **kw)
return decorator(caller)(func)
return entagle

after:

def foo(a):
def entagle(func)
def caller(func, *args, **kw):
func(*args, **kw)
return caller
return decorator(entagle)

As an added bonus it is also marginally more concise.

While I was at it, I made another change. Until now decorator() added
*args and **kw to the resulting function signature unless optional
argument "argsink" was false.
Well, "argsink" is no more. Instead we have a much more powerful (still
optional) argument "signature" similar in composition to what
inspect.getargspec() returns, allowing us to define an arbitrary
signatures (mind, the function being decorated still needs to be able to
digest this new parameter specification).
To get the beloved care-free will-eat-anything signatures back a helper
named weak_signature_decorator() is available.

I invite all interested to take a look at decorator.py and
test_decorator.py. The use of signature in anger can be observed in
util.bind_args().

Knowing myself I suggest we keep it in trunk for a while (maybe until
after the sprint and than send it into the wild with nice and shiny
documentation by it's side).

Cheers,
Simon

Kevin Dangoor

unread,
Apr 27, 2006, 9:53:26 PM4/27/06
to turbogea...@googlegroups.com
On 4/27/06, Simon Belak <simon...@hruska.si> wrote:
> I'm going to make everyone's life miserable again. ;)
>
> In r1279 I added support for "alternative" decorator syntax as used by
> PEAK to lessen the anguish of people still on Python 2.3. This
> unfortunately requires a bit different application of decorator() function.

This change needs to be in a5. I don't want to do another alpha
release, and I don't want to see this wait until 1.1. Do we have any
other code that is impacted that needs changing? Is there any way to
provide backwards compatibility?

Kevin

Jorge Godoy

unread,
Apr 27, 2006, 10:21:23 PM4/27/06
to turbogea...@googlegroups.com

I am trying to make old code work with this... I'm sending another message
describing my problems.

Maybe I had wrong code before -- it worked perfectly before, though -- and now
I have it fixed, but...

--
Jorge Godoy <jgo...@gmail.com>

Jorge Godoy

unread,
Apr 27, 2006, 10:40:18 PM4/27/06
to turbogea...@googlegroups.com
Em Quinta 27 Abril 2006 19:42, Simon Belak escreveu:
> Hi,
>
> I'm going to make everyone's life miserable again. ;)
>
> In r1279 I added support for "alternative" decorator syntax as used by
> PEAK to lessen the anguish of people still on Python 2.3. This
> unfortunately requires a bit different application of decorator() function.
>
> Before:
>
> def foo(a):
> def entagle(func)
> def caller(func, *args, **kw):
> func(*args, **kw)
> return decorator(caller)(func)
> return entagle
>
> after:
>
> def foo(a):
> def entagle(func)
> def caller(func, *args, **kw):
> func(*args, **kw)
> return caller
> return decorator(entagle)
>
> As an added bonus it is also marginally more concise.

I had, before:

@decorator
def my_decorator(func, *args, **kwords):
...

How should I translate it to the new syntax? I'm not worried with supporting
Python 2.3 here, so the easiness of the old syntax was very nice to me.

> While I was at it, I made another change. Until now decorator() added
> *args and **kw to the resulting function signature unless optional
> argument "argsink" was false.
> Well, "argsink" is no more. Instead we have a much more powerful (still
> optional) argument "signature" similar in composition to what
> inspect.getargspec() returns, allowing us to define an arbitrary
> signatures (mind, the function being decorated still needs to be able to
> digest this new parameter specification).
> To get the beloved care-free will-eat-anything signatures back a helper
> named weak_signature_decorator() is available.

I tried it as well, but it won't work with the above (mine) syntax. I had to
convert to your syntax to have it working... But then, I started having
other problems, specially with @turbogears.validate, which is failing always.

> I invite all interested to take a look at decorator.py and
> test_decorator.py. The use of signature in anger can be observed in
> util.bind_args().
>
> Knowing myself I suggest we keep it in trunk for a while (maybe until
> after the sprint and than send it into the wild with nice and shiny
> documentation by it's side).

Here are my "attempts":

===============================================================================
def mensagem_json():
def entangle(func):
def caller(func, *args, **kwords):
print "#################"
return caller
return decorator(entangle)
===============================================================================

What results in:

===============================================================================
Traceback (most recent call last):
File "./start-siteamostras.py", line 26, in ?
from siteamostras.controllers import Root
File
"/home/godoy/empresa/clientes/latam/Site-Amostras/siteamostras/controllers/__init__.py",
line 18, in ?
from siteamostras.controllers.toxicologia import Toxicologia
File
"/home/godoy/empresa/clientes/latam/Site-Amostras/siteamostras/controllers/toxicologia.py",
line 24, in ?
from siteamostras.controllers import analises
File
"/home/godoy/empresa/clientes/latam/Site-Amostras/siteamostras/controllers/analises.py",
line 29, in ?
class Analises(controllers.Controller):
File
"/home/godoy/empresa/clientes/latam/Site-Amostras/siteamostras/controllers/analises.py",
line 213, in Analises
@turbogears.expose()
TypeError: mensagem_json() takes no arguments (1 given)
===============================================================================

When I change it to:

===============================================================================
def mensagem_json(something):
def entangle(func):
def caller(func, *args, **kwords):
print "#################"
return caller
return decorator(entangle)
===============================================================================

it runs, but @turbogears.validate fails.

Changing it to:

===============================================================================
def mensagem_json(func):
def entangle(func):
def caller(func, *args, **kwords):
print "#################"
return caller
return decorator(entangle)
===============================================================================

Using weak_signature_decorator doesn't help and yields the same results.


In my code I have:

===============================================================================
@turbogears.expose()
@turbogears.error_handler(turbogears.util.bind_args(add = True)(analises))
@turbogears.validate(form = formulario_analises)
@identity.require(identity.conditions.in_group("latam_novo"))
@mensagem_json
def save(self, **kword):
...
===============================================================================

I hope I'm doing something wrong and that is easy to solve.

--
Jorge Godoy <jgo...@gmail.com>

Kevin Dangoor

unread,
Apr 28, 2006, 6:38:01 AM4/28/06
to turbogea...@googlegroups.com
On 4/27/06, Simon Belak <simon...@hruska.si> wrote:
> In r1279 I added support for "alternative" decorator syntax as used by
> PEAK to lessen the anguish of people still on Python 2.3. This
> unfortunately requires a bit different application of decorator() function.

Sorry if my message last night sounded terse. I didn't have much time
just then...

I have one other question about this: is there any perceptible
difference in startup time? startup time is actually somewhat
important, because the user has to sit through that startup time every
time they make a change to their code during development. I'd rather
not dramatically slow down use for Py2.4 users. If there isn't a big
startup cost, then this is a really nice change for 2.3 users (and
those of use working on TG itself!)

Kevin

Simon Belak

unread,
Apr 28, 2006, 6:49:37 AM4/28/06
to turbogea...@googlegroups.com
Kevin Dangoor wrote:
> On 4/27/06, Simon Belak <simon...@hruska.si> wrote:
>> In r1279 I added support for "alternative" decorator syntax as used by
>> PEAK to lessen the anguish of people still on Python 2.3. This
>> unfortunately requires a bit different application of decorator() function.

> I have one other question about this: is there any perceptible


> difference in startup time? startup time is actually somewhat
> important, because the user has to sit through that startup time every
> time they make a change to their code during development. I'd rather
> not dramatically slow down use for Py2.4 users. If there isn't a big
> startup cost, then this is a really nice change for 2.3 users (and
> those of use working on TG itself!)

Penalty is a couple of function calls per decorator. Nothing wild.

I intend to make some changes to not burden people who do not need 2.3
compatibility (see Jorge's example) and than merge with a5.

Cheers
Simon

Kevin Dangoor

unread,
Apr 28, 2006, 6:51:18 AM4/28/06
to turbogea...@googlegroups.com
On 4/28/06, Simon Belak <simon...@hruska.si> wrote:
> Penalty is a couple of function calls per decorator. Nothing wild.

That's not too bad. I was worried about the whole "debug hook" thing
slowing things down.

> I intend to make some changes to not burden people who do not need 2.3
> compatibility (see Jorge's example) and than merge with a5.

That's great! Thanks!

Kevin

Simon Belak

unread,
Apr 28, 2006, 11:04:10 AM4/28/06
to turbogea...@googlegroups.com
Forgot to mention, decorator() and weak_signature_decorator() expect a
closure. In your case

def mensagem_json():
def entangle(func):
def caller(func, *args, **kwords):
print "#################"
return caller

return weak_signature_decorator(entangle)

....

@mensagem_json()
def ...

should do the trick.

As of 1285 two new decorator factories are available:

simple_decorator()
simple_simple_weak_signature_decorator()

which work as before (apply to caller, no Py2.3 compatibility).

I would however very much appreciate if you could also try to make the
new weak_signature_decorator() work with your code, just to make sure
before I apply these changes to a5. Thanks!

Cheers,
Simon

Jorge Godoy

unread,
Apr 28, 2006, 11:27:00 AM4/28/06
to turbogea...@googlegroups.com
Em Sexta 28 Abril 2006 12:04, Simon Belak escreveu:
> Forgot to mention, decorator() and weak_signature_decorator() expect a
> closure. In your case
>
> def mensagem_json():
> def entangle(func):
> def caller(func, *args, **kwords):
> print "#################"
> return caller
> return weak_signature_decorator(entangle)
>
> ....
>
> @mensagem_json()
> def ...
>
> should do the trick.

It didn't.

> As of 1285 two new decorator factories are available:
>
> simple_decorator()
> simple_simple_weak_signature_decorator()
>
> which work as before (apply to caller, no Py2.3 compatibility).

They still give me errors. Second is with simple_weak_signature_decorator.


godoy@jupiter ~/empresa/clientes/latam/Site-Amostras % ./start-siteamostras.py


Traceback (most recent call last):
File "./start-siteamostras.py", line 26, in ?
from siteamostras.controllers import Root
File
"/home/godoy/empresa/clientes/latam/Site-Amostras/siteamostras/controllers/__init__.py",
line 18, in ?
from siteamostras.controllers.toxicologia import Toxicologia
File
"/home/godoy/empresa/clientes/latam/Site-Amostras/siteamostras/controllers/toxicologia.py",
line 24, in ?
from siteamostras.controllers import analises
File
"/home/godoy/empresa/clientes/latam/Site-Amostras/siteamostras/controllers/analises.py",

line 24, in ?
from siteamostras.decorador import mensagem_json
File
"/home/godoy/empresa/clientes/latam/Site-Amostras/siteamostras/decorador.py",
line 18, in ?
@decorator()
TypeError: simple_decorator() takes at least 1 argument (0 given)
godoy@jupiter ~/empresa/clientes/latam/Site-Amostras % ./start-siteamostras.py


Traceback (most recent call last):
File "./start-siteamostras.py", line 26, in ?
from siteamostras.controllers import Root
File
"/home/godoy/empresa/clientes/latam/Site-Amostras/siteamostras/controllers/__init__.py",
line 18, in ?
from siteamostras.controllers.toxicologia import Toxicologia
File
"/home/godoy/empresa/clientes/latam/Site-Amostras/siteamostras/controllers/toxicologia.py",
line 24, in ?
from siteamostras.controllers import analises
File
"/home/godoy/empresa/clientes/latam/Site-Amostras/siteamostras/controllers/analises.py",
line 29, in ?
class Analises(controllers.Controller):
File
"/home/godoy/empresa/clientes/latam/Site-Amostras/siteamostras/controllers/analises.py",
line 213, in Analises
@turbogears.expose()

TypeError: entangle() takes exactly 1 argument (0 given)
godoy@jupiter ~/empresa/clientes/latam/Site-Amostras %

> I would however very much appreciate if you could also try to make the
> new weak_signature_decorator() work with your code, just to make sure
> before I apply these changes to a5. Thanks!

I'm trying that for hours :-)

May I send you my decorator off list so that you take a look and see what I'm
doing wrong? :-)

--
Jorge Godoy <jgo...@gmail.com>

Simon Belak

unread,
Apr 28, 2006, 11:32:29 AM4/28/06
to turbogea...@googlegroups.com

Please do.

Cheers,
Simon

Jorge Godoy

unread,
Apr 28, 2006, 11:36:01 AM4/28/06
to turbogea...@googlegroups.com
Em Sexta 28 Abril 2006 12:32, Simon Belak escreveu:
> > May I send you my decorator off list so that you take a look and see what
> > I'm doing wrong? :-)
>
> Please do.

Done. Thanks! :-)

--
Jorge Godoy <jgo...@gmail.com>

Simon Belak

unread,
Apr 28, 2006, 3:43:29 PM4/28/06
to turbogea...@googlegroups.com
Kevin Dangoor wrote:
>> I intend to make some changes to not burden people who do not need 2.3
>> compatibility (see Jorge's example) and than merge with a5.

Commited into 1.0 branch as 1290.

Cheers,
Simon

Kevin Dangoor

unread,
Apr 28, 2006, 4:26:33 PM4/28/06
to turbogea...@googlegroups.com
On 4/28/06, Simon Belak <simon...@hruska.si> wrote:
>

I tried a quick test of it. Looks good!

Kevin

Jorge Godoy

unread,
Apr 28, 2006, 4:37:03 PM4/28/06
to turbogea...@googlegroups.com

And works with "legacy" decorators ;-) One just has to

from turbogears.decorator import simple_decorator as decorator

and he can keep using the old syntax.

Simon did a great job with this compatibility layer! Really good!

--
Jorge Godoy <jgo...@gmail.com>

Simon Belak

unread,
Apr 29, 2006, 5:09:44 PM4/29/06
to turbogea...@googlegroups.com

Just to clarify, simple_decorator and family are not intended solely for
backward compatibility, my main motivation was reducing boilerplate and
not have the user adjust to the framework but vice versa.

Cheers,
Simon

Reply all
Reply to author
Forward
0 new messages