liveevil problem: nested functions get lost
Hi all, I don't know if this is a known problem or the way it is supposed to work but the following code results in a "lost" liveevil handler: class Blah(rend.Page): def render_blah(self, ctx, data): def do_something(client): client.alert("You will never see this message!") return ctx.tag.clear()[T.span( onclick=liveevil.handler(do_something))["Click me"]] The do_something is not recognized as a closure (actually it is not :) so its "path" is saved away as module.do_something and does not get resolved at call time. I know about the identifier keyword something about it should probably be added to the docs. Maybe is would be even better (and safer) to remove the reflect part and use only the events. federico
I think I encountered similar symptoms once and after quite some time of confusion I concluded that it must have to do with python's garbage collector. It seemed to me that there needs to be something refereced in the do_something() method to prevent it from being wiped before the call comes back from the client. In most of my code (like in the following example) I have a referenced variable and therefore it works. But I totally agree this behavior should be documented otherwise it can be very frustrating. #noema This structure works resolves correctly: class Blah(rend.Page): def render_blah(self, ctx, data): def do_something(client): some_variable client.alert("You will never see this message!") some_variable = None return ctx.tag.clear()[T.span( onclick=liveevil.handler(do_something))["Click me"]] Federico Di Gregorio wrote:
Hi all,
I don't know if this is a known problem or the way it is supposed to work but the following code results in a "lost" liveevil handler:
class Blah(rend.Page): def render_blah(self, ctx, data): def do_something(client): client.alert("You will never see this message!") return ctx.tag.clear()[T.span( onclick=liveevil.handler(do_something))["Click me"]]
The do_something is not recognized as a closure (actually it is not :) so its "path" is saved away as module.do_something and does not get resolved at call time. I know about the identifier keyword something about it should probably be added to the docs. Maybe is would be even better (and safer) to remove the reflect part and use only the events.
federico
_______________________________________________ Twisted-web mailing list Twisted-web@twistedmatrix.com http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-web
Il giorno ven, 25-02-2005 alle 21:47 -0800, noema ha scritto:
I think I encountered similar symptoms once and after quite some time of confusion I concluded that it must have to do with python's garbage collector. It seemed to me that there needs to be something refereced in the do_something() method to prevent it from being wiped before the call comes back from the client.
That's why if you use "identifier" the handler is managed in a different way (using events instead of reflect) and keeps a reference to the callable object. Just I don't like to have to put "identifier" everywhere, it would be much better to define handlers in a uniform way without having to know what kind of callable you're passing as argument. federico -- Federico Di Gregorio http://people.initd.org/fog Debian GNU/Linux Developer fog@debian.org INIT.D Developer fog@initd.org Abandon the search for Truth; settle for a good fantasy. -- Anonymous
On Feb 27, 2005, at 12:55 PM, Federico Di Gregorio wrote:
Il giorno ven, 25-02-2005 alle 21:47 -0800, noema ha scritto:
I think I encountered similar symptoms once and after quite some time of confusion I concluded that it must have to do with python's garbage collector. It seemed to me that there needs to be something refereced in the do_something() method to prevent it from being wiped before the call comes back from the client.
That's why if you use "identifier" the handler is managed in a different way (using events instead of reflect) and keeps a reference to the callable object. Just I don't like to have to put "identifier" everywhere, it would be much better to define handlers in a uniform way without having to know what kind of callable you're passing as argument.
Using the function name as the identifier was an experiment which I think was a bad idea. I'll roll that code back out. Before I started using the function name, I used an arbitrary identifier which was opaque and made debugging difficult. With the addition of the programmer-supplied identifier, debugging can be made easier by providing it, and an opaque identifier can be used if none is provided. dp
Il giorno lun, 28-02-2005 alle 08:26 -0800, Donovan Preston ha scritto:
Using the function name as the identifier was an experiment which I think was a bad idea. I'll roll that code back out.
Before I started using the function name, I used an arbitrary identifier which was opaque and made debugging difficult. With the addition of the programmer-supplied identifier, debugging can be made easier by providing it, and an opaque identifier can be used if none is provided.
I completely agree. Sorry for the noise but I stopped following the HEAD for some weeks so I somehow lost the "story" of the changes. Another little problem: isn't liveevil.js missing an eval() call on the handler extra arguments? -- Federico Di Gregorio http://people.initd.org/fog Debian GNU/Linux Developer fog@debian.org INIT.D Developer fog@initd.org stiamo parlando di lesbiche. secondo te ce ne frega qualcosa? -- <Md>
On Feb 28, 2005, at 8:34 AM, Federico Di Gregorio wrote:
Il giorno lun, 28-02-2005 alle 08:26 -0800, Donovan Preston ha scritto:
Using the function name as the identifier was an experiment which I think was a bad idea. I'll roll that code back out.
Before I started using the function name, I used an arbitrary identifier which was opaque and made debugging difficult. With the addition of the programmer-supplied identifier, debugging can be made easier by providing it, and an opaque identifier can be used if none is provided.
I completely agree. Sorry for the noise but I stopped following the HEAD for some weeks so I somehow lost the "story" of the changes.
Another little problem: isn't liveevil.js missing an eval() call on the handler extra arguments?
No; python string literals are now treated as javascript string literals. To produce a javascript string which won't get quoted (and thus will be evaled when it arrives in the browser) you should now use the nevow.livepage.literal string wrapper. The name "literal" will probably change to "js" or something more suitable soon. (Suggestions please?) dp
Il giorno lun, 28-02-2005 alle 14:17 -0800, Donovan Preston ha scritto:
Another little problem: isn't liveevil.js missing an eval() call on the handler extra arguments?
No; python string literals are now treated as javascript string literals. To produce a javascript string which won't get quoted (and thus will be evaled when it arrives in the browser) you should now use the nevow.livepage.literal string wrapper. The name "literal" will probably change to "js" or something more suitable soon. (Suggestions please?)
So the string won't be evaluated in the context of the nevow_clientToServerEvent() function but directly in the event call, isn't it? So hanlders like: handler(mycallable, "node.value") should now be written: handler(mycallable, liveevil.js("this.value")) substituting "this" to "node"? It is fine for me and even the "js" name is not too bad (i.e., I can't think of anything better right now.) federico -- Federico Di Gregorio http://people.initd.org/fog Debian GNU/Linux Developer fog@debian.org INIT.D Developer fog@initd.org Nessuno dice che non si possa sognare in dettaglio, essere realistici e magari realizzarlo pure, il sogno. -- <dani>
On Feb 28, 2005, at 3:09 PM, Federico Di Gregorio wrote:
So the string won't be evaluated in the context of the nevow_clientToServerEvent() function but directly in the event call, isn't it? So hanlders like:
handler(mycallable, "node.value")
should now be written:
handler(mycallable, liveevil.js("this.value"))
substituting "this" to "node"? It is fine for me and even the "js" name is not too bad (i.e., I can't think of anything better right now.)
That is correct, and I hope it is ok. The way "literal" (to be renamed "js") is written is very convenient, too: handler(mycallable, liveevil.js.this.value) Would work just as well (__getattr__ constructs new literal instances). There is already a module-global "document" literal, so you can do livepage.document.getElementById. literal (js) provides __getitem__ as well as __call__ implementations. I hope it all makes sense, it is somewhat experimental at this point. One good thing about this new implementation is that there are extensive javascript quoting unittests, where there were none before, so hopefully it is less buggy, more flexible, and less likely to change in the future. dp
Il giorno lun, 28-02-2005 alle 17:54 -0800, Donovan Preston ha scritto:
On Feb 28, 2005, at 3:09 PM, Federico Di Gregorio wrote:
substituting "this" to "node"? It is fine for me and even the "js" name is not too bad (i.e., I can't think of anything better right now.)
That is correct, and I hope it is ok. The way "literal" (to be renamed "js") is written is very convenient, too:
handler(mycallable, liveevil.js.this.value)
Would work just as well (__getattr__ constructs new literal instances). There is already a module-global "document" literal, so you can do livepage.document.getElementById. literal (js) provides __getitem__ as well as __call__ implementations.
Usefull. Can we also have a module-global "this"? And maybe "window"? document, window and this are almost the only JS globals I can think of that are used in a normal page.
I hope it all makes sense, it is somewhat experimental at this point. One good thing about this new implementation is that there are extensive javascript quoting unittests, where there were none before, so hopefully it is less buggy, more flexible, and less likely to change in the future.
Great. :) federico -- Federico Di Gregorio http://people.initd.org/fog Debian GNU/Linux Developer fog@debian.org INIT.D Developer fog@initd.org Sei una bergogna. Vergonga. Vergogna. -- Valentina
On Mar 1, 2005, at 12:47 AM, Federico Di Gregorio wrote:
Usefull. Can we also have a module-global "this"? And maybe "window"? document, window and this are almost the only JS globals I can think of that are used in a normal page.
Yes. I was going to go through my JavaScript book and make module-level globals for all the various things you would use in a globaly way from javascript. dp
On Tue, 1 Mar 2005 07:17:19 -0800, Donovan Preston <dp@ulaluma.com> wrote:
Yes. I was going to go through my JavaScript book and make module-level globals for all the various things you would use in a globaly way from javascript.
Why not js.document, js.global ..? -- Sridhar Ratna - http://srid.bsdnerds.org
On Tue, 01 Mar 2005 00:09:01 +0100, Federico Di Gregorio <fog@initd.org> wrote:
should now be written:
handler(mycallable, liveevil.js("this.value"))
Or handler(mycallable, liveevil.js('this').value) hmm, now I could think of the power of Lisp. Python can just do literals (in obvious way). :-) -- Sridhar Ratna - http://srid.bsdnerds.org
participants (4)
-
Donovan Preston
-
Federico Di Gregorio
-
noema
-
Sridhar Ratna