librelist archives

« back to archive

Re: [flask] Hard Flask Crash

Re: [flask] Hard Flask Crash

From:
Clayton Cafiero
Date:
2012-06-20 @ 20:33
Hi Jonathan:

Did anything ever come of this? (Your message is about a year old!) I can 
reproduce your result, and am having the same problem with

Babel==0.9.6
Flask==0.8
Flask-Babel==0.8
Jinja2==2.6
speaklater==1.2
Werkzeug==0.8.3
…

Using lazy_gettext for strings used in flash messages results in hard 
crash. Switching to gettext resolves the issue (but is an unsatisfactory 
workaround for me).

Any news?

Anyone else?

THANKS

- Clayton Cafiero



>> On Sun, Jun 26, 2011 at 10:16 PM, Jonathan Zempel <jzempel@gmail.com> wrote:
>> 
>> I've got a scenario where I'm reproducing a severe Flask crash.  The
>> elements include:
>> 
>>  Flask-Babel lazy_gettext + Flask flash get_flashed_messages + ???
>>  (Flask-Script "runserver" maybe?) == un-reported, un-catchable crash.
>> 
>> Actually, anything that dereferences a session that contains lazy_gettext
>> messages will crash hard.  I've spent several days in and out of this
>> problem.  I still haven't exactly isolated the cause, and will continue to
>> work on that.  In the mean time, does this sound familiar to anyone?  If I
>> use Flask-Babel "gettext" for the flash messages, the crash goes away.
>> Also, am I violating any kind of best practice for lazy translating flash
>> messages?
>> 
>> My current environment:
>> 
>> Werkzeug==0.7dev
>> Jinja2==2.6dev
>> Flask==0.6.1
>> Flask-Babel==0.6
>> 
>> Although I've reproduced with the werkzueg+jinja versions required by Flask
>> 0.6.1.
>> 
>> Thanks,
>> Jonathan.

> I'm following-up on this post with a more accurate baseline and test harness
> for reproducing the issue.  The basic environment is:
> 
> Werkzeug==0.6.2
> Jinja2==2.5.5
> Flask==0.6.1
> Flask-Babel==0.6
> Flask-Script==0.3.1
> 
> These are the combined elements that contribute to an exception:
> 
> 1) HTTP POST
> 2) Use lazy_gettext to add a "flash" message
> 3) HTTP redirect (302) to a render_template path
> 4) Loop through "get_flashed_messages" to display flash messages in the
> template
> 
> At this point, there is a "maximum recursion depth exceeded" runtime
> exception coming out of speaklater (used by Babel).
> 
> 5) If Flask-Script is used to "runserver", then the dev server (on port
> 5000) will crash hard without the ability to catch the exception.
> 
> The test code and HTML template are pasted below.  Right now, the workaround
> for me is to change from lazy_gettext to gettext.  But I'd appreciate any
> feedback or best practice for improving the pattern here.
> 
> Thanks again,
> Jonathan.
> 
> ~~~~~
> test.py
> ~~~~~
> from flask import _request_ctx_stack, flash, Flask, redirect, \
>     render_template, request, url_for
> from flaskext.babel import Babel, gettext, lazy_gettext
> #from flaskext.script import Manager
> from traceback import format_exc
> 
> app = Flask(__name__)
> app.config["SECRET_KEY"] = "secret"
> Babel(app)
> 
> @app.route("/", methods=["GET"])
> def get():
>     try:
>         # Lazy gettext on HTTP GET works fine.
>         message = lazy_gettext("Hello World!")
>         flash(message)
>         return render_template("test.html")
>     except Exception:
>         return format_exc()
> 
> @app.route("/", methods=["POST"])
> def post():
>     # Exception goes away if the following is gettext.
>     message = lazy_gettext("Goodbye World.")
>     flash(message)
>     url = url_for("get")
> 
>     return redirect(url)
> 
> #manager = Manager(app)
> 
> if __name__ == "__main__":
>     app.run()
>     #manager.run() # <- Use this to crash the running server.
> 
> ~~~~~~~~~~~~~~
> templates/test.html
> ~~~~~~~~~~~~~~
> <!DOCTYPE html>
> <html lang="en">
> <head>
>     <meta charset="utf-8" />
> </head>
> <body>
>     {% for category, message in get_flashed_messages(with_categories=true)
> %}
>     <div>{{ message }}</div>
>     {% endfor %}
>     <form action="{{ url_for("post") }}" method="post">
>         <input type="submit" />
>     </form>
> </body>
> </html>

Re: [flask] Hard Flask Crash

From:
Simon Sapin
Date:
2012-06-21 @ 05:44
Le 20/06/2012 22:33, Clayton Cafiero a écrit :
> Hi Jonathan:
>
> Did anything ever come of this? (Your message is about a year old!)
> I  can reproduce your result, and am having the same problem with
>
> Babel==0.9.6
> Flask==0.8
> Flask-Babel==0.8
> Jinja2==2.6
> speaklater==1.2
> Werkzeug==0.8.3
> …
>
> Using lazy_gettext for strings used in flash messages results in hard
> crash. Switching to gettext resolves the issue (but is an
> unsatisfactory workaround for me).

Hi,

If you get a crash (segfault?) without a traceback, try faulthandler to 
get a traceback anyway:

http://pypi.python.org/pypi/faulthandler/

     import faulthandler
     faulthandler.enable()
     # Continue the rest of the script …

Please copy the full traceback with the relevant parts of your code so 
we can get an idea of what’s going on.

Regards,
-- 
Simon Sapin

Re: [flask] Hard Flask Crash

From:
Clayton Cafiero
Date:
2012-06-21 @ 21:02
Hi Simon.

I've pared things down a bit for readability. You can view a test (based 
largely on Jonathan Zempel's test, posted earlier) and a traceback at 
https://gist.github.com/2968483. Bottom line (literally) is "RuntimeError:
maximum recursion depth exceeded". Should one expect this result when 
using lazy_gettext? Again, this occurs when using lazy_gettext() to supply
a message to flash() and then calling redirect(). Odd. (If we toss 
sessions into the mix we can get a hard crash, but this appears to be the 
root cause.) 

THANKS VERY MUCH FOR YOUR HELP.

Regards,

-Clayton

---------------------------------------------------------

Clayton Cafiero

Monday Lambson, Inc.
P.O. Box 4537
Burlington, VT 05406
U.S.A.

Tel: +1 (802) 735-8744
Skype: clayton.cafiero
http://mondaylambson.com/

clayton.cafiero@mondaylambson.com






On 2012-06-21, at 01:44 AM, Simon Sapin wrote:

> Le 20/06/2012 22:33, Clayton Cafiero a écrit :
>> Hi Jonathan:
>> 
>> Did anything ever come of this? (Your message is about a year old!)
>> I  can reproduce your result, and am having the same problem with
>> 
>> Babel==0.9.6
>> Flask==0.8
>> Flask-Babel==0.8
>> Jinja2==2.6
>> speaklater==1.2
>> Werkzeug==0.8.3
>> …
>> 
>> Using lazy_gettext for strings used in flash messages results in hard
>> crash. Switching to gettext resolves the issue (but is an
>> unsatisfactory workaround for me).
> 
> Hi,
> 
> If you get a crash (segfault?) without a traceback, try faulthandler to 
> get a traceback anyway:
> 
> http://pypi.python.org/pypi/faulthandler/
> 
>     import faulthandler
>     faulthandler.enable()
>     # Continue the rest of the script …
> 
> Please copy the full traceback with the relevant parts of your code so 
> we can get an idea of what’s going on.
> 
> Regards,
> -- 
> Simon Sapin

Re: [flask] Hard Flask Crash

From:
Simon Sapin
Date:
2012-06-21 @ 21:24
Le 21/06/2012 23:02, Clayton Cafiero a écrit :
> Hi Simon.
>
> I've pared things down a bit for readability. You can view a test (based
> largely on Jonathan Zempel's test, posted earlier) and a traceback at
> https://gist.github.com/2968483. Bottom line (literally) is
> "RuntimeError: maximum recursion depth exceeded". Should one expect this
> result when using lazy_gettext? Again, this occurs when using
> lazy_gettext() to supply a message to flash() and then calling
> redirect(). Odd. (If we toss sessions into the mix we can get a hard
> crash, but this appears to be the root cause.)
>
> THANKS VERY MUCH FOR YOUR HELP.

Ok, here is what I gather from your traceback:

Your message object in {{ message }} is a LazyString instance from the 
speaklater library:

https://github.com/mitsuhiko/speaklater/blob/master/speaklater.py#L102

For some reason, this object does not have a _func attribute. Jinja 
calls its __unicode__ method, which access the `value` property, which 
access the `_func` attribute. Since the attribute is missing, this calls 
__getattr__ which calls the `value` property which access the `_func` 
attribute …

After a while, you hit the recursion limit. I don’t know why you get a 
"hard crash" (whatever that is) rather than a proper traceback but meh.

Now, how did we get this object with a missing attribute? Apparently it 
went through a session, which I think default to pickling. The 
__getstate__ and __setstate__ should cover this, and they look fine.

First, please check which version of speaklater you are running. Is it 
the same as the git master I’m looking at?

Then, make a _LazyString object with lazy_gettext(). Try to access its 
`value` property:

* Immediately
* After the object has gone through pickling and un-pickling using the 
pickle module from the standard library.
* After it has be serialized and serialized in a Flask session

Please report which work or not. Also, at each point, try this:
object.__getattribute__(the_lazystring_object, 'value')

The goal is to find at which point something goes wrong.

Good luck,
-- 
Simon Sapin

Re: [flask] Hard Flask Crash

From:
Clayton Cafiero
Date:
2012-06-21 @ 21:44
Simon:

Thanks for the help. I'm using speaklater 1.2 and will work up a test that
checks the value property of the _LazyString object as you suggest. Will 
report back soon.

Thanks again,

-Clayton



On 2012-06-21, at 05:24 PM, Simon Sapin wrote:

> Le 21/06/2012 23:02, Clayton Cafiero a écrit :
>> Hi Simon.
>> 
>> I've pared things down a bit for readability. You can view a test (based
>> largely on Jonathan Zempel's test, posted earlier) and a traceback at
>> https://gist.github.com/2968483. Bottom line (literally) is
>> "RuntimeError: maximum recursion depth exceeded". Should one expect this
>> result when using lazy_gettext? Again, this occurs when using
>> lazy_gettext() to supply a message to flash() and then calling
>> redirect(). Odd. (If we toss sessions into the mix we can get a hard
>> crash, but this appears to be the root cause.)
>> 
>> THANKS VERY MUCH FOR YOUR HELP.
> 
> Ok, here is what I gather from your traceback:
> 
> Your message object in {{ message }} is a LazyString instance from the 
> speaklater library:
> 
> https://github.com/mitsuhiko/speaklater/blob/master/speaklater.py#L102
> 
> For some reason, this object does not have a _func attribute. Jinja 
> calls its __unicode__ method, which access the `value` property, which 
> access the `_func` attribute. Since the attribute is missing, this calls 
> __getattr__ which calls the `value` property which access the `_func` 
> attribute …
> 
> After a while, you hit the recursion limit. I don’t know why you get a 
> "hard crash" (whatever that is) rather than a proper traceback but meh.
> 
> Now, how did we get this object with a missing attribute? Apparently it 
> went through a session, which I think default to pickling. The 
> __getstate__ and __setstate__ should cover this, and they look fine.
> 
> First, please check which version of speaklater you are running. Is it 
> the same as the git master I’m looking at?
> 
> Then, make a _LazyString object with lazy_gettext(). Try to access its 
> `value` property:
> 
> * Immediately
> * After the object has gone through pickling and un-pickling using the 
> pickle module from the standard library.
> * After it has be serialized and serialized in a Flask session
> 
> Please report which work or not. Also, at each point, try this:
> object.__getattribute__(the_lazystring_object, 'value')
> 
> The goal is to find at which point something goes wrong.
> 
> Good luck,
> -- 
> Simon Sapin

Re: [flask] Hard Flask Crash

From:
Jonathan Zempel
Date:
2012-06-22 @ 20:29
Clayton,

Thanks for pursuing this long-standing issue. I've worked-up the test that
Simon suggested. https://gist.github.com/2974967

The "max recursion" exception happens when 'value' is dereferenced on a
pickled _LazyString (either standard pickle or via Flask session).

I haven't yet dug into answering "why".

Jonathan.

On Thu, Jun 21, 2012 at 2:44 PM, Clayton Cafiero <
clayton.cafiero@mondaylambson.com> wrote:

> Simon:
>
> Thanks for the help. I'm using speaklater 1.2 and will work up a test that
> checks the value property of the _LazyString object as you suggest. Will
> report back soon.
>
> Thanks again,
>
> -Clayton
>
>
>
> On 2012-06-21, at 05:24 PM, Simon Sapin wrote:
>
> Le 21/06/2012 23:02, Clayton Cafiero a écrit :
>
> Hi Simon.
>
>
> I've pared things down a bit for readability. You can view a test (based
>
> largely on Jonathan Zempel's test, posted earlier) and a traceback at
>
> https://gist.github.com/2968483. Bottom line (literally) is
>
> "RuntimeError: maximum recursion depth exceeded". Should one expect this
>
> result when using lazy_gettext? Again, this occurs when using
>
> lazy_gettext() to supply a message to flash() and then calling
>
> redirect(). Odd. (If we toss sessions into the mix we can get a hard
>
> crash, but this appears to be the root cause.)
>
>
> THANKS VERY MUCH FOR YOUR HELP.
>
>
> Ok, here is what I gather from your traceback:
>
> Your message object in {{ message }} is a LazyString instance from the
> speaklater library:
>
> https://github.com/mitsuhiko/speaklater/blob/master/speaklater.py#L102
>
> For some reason, this object does not have a _func attribute. Jinja
> calls its __unicode__ method, which access the `value` property, which
> access the `_func` attribute. Since the attribute is missing, this calls
> __getattr__ which calls the `value` property which access the `_func`
> attribute …
>
> After a while, you hit the recursion limit. I don’t know why you get a
> "hard crash" (whatever that is) rather than a proper traceback but meh.
>
> Now, how did we get this object with a missing attribute? Apparently it
> went through a session, which I think default to pickling. The
> __getstate__ and __setstate__ should cover this, and they look fine.
>
> First, please check which version of speaklater you are running. Is it
> the same as the git master I’m looking at?
>
> Then, make a _LazyString object with lazy_gettext(). Try to access its
> `value` property:
>
> * Immediately
> * After the object has gone through pickling and un-pickling using the
> pickle module from the standard library.
> * After it has be serialized and serialized in a Flask session
>
> Please report which work or not. Also, at each point, try this:
> object.__getattribute__(the_lazystring_object, 'value')
>
> The goal is to find at which point something goes wrong.
>
> Good luck,
> --
> Simon Sapin
>
>
>

Re: [flask] Hard Flask Crash

From:
Clayton Cafiero
Date:
2012-06-22 @ 20:37
Jonathan:

Dang. You beat me to it.

Excellent.

I'll take a look at your test and see if I can make sense of it. 

Perhaps Simon can divine the cause.

Thanks!

-Clayton


On 2012-06-22, at 04:29 PM, Jonathan Zempel wrote:

> Clayton,
> 
> Thanks for pursuing this long-standing issue. I've worked-up the test 
that Simon suggested. https://gist.github.com/2974967
> 
> The "max recursion" exception happens when 'value' is dereferenced on a 
pickled _LazyString (either standard pickle or via Flask session).
> 
> I haven't yet dug into answering "why".
> 
> Jonathan.
> 
> On Thu, Jun 21, 2012 at 2:44 PM, Clayton Cafiero 
<clayton.cafiero@mondaylambson.com> wrote:
> Simon:
> 
> Thanks for the help. I'm using speaklater 1.2 and will work up a test 
that checks the value property of the _LazyString object as you suggest. 
Will report back soon.
> 
> Thanks again,
> 
> -Clayton
> 
> 
> 
> On 2012-06-21, at 05:24 PM, Simon Sapin wrote:
> 
>> Le 21/06/2012 23:02, Clayton Cafiero a écrit :
>>> Hi Simon.
>>> 
>>> I've pared things down a bit for readability. You can view a test (based
>>> largely on Jonathan Zempel's test, posted earlier) and a traceback at
>>> https://gist.github.com/2968483. Bottom line (literally) is
>>> "RuntimeError: maximum recursion depth exceeded". Should one expect this
>>> result when using lazy_gettext? Again, this occurs when using
>>> lazy_gettext() to supply a message to flash() and then calling
>>> redirect(). Odd. (If we toss sessions into the mix we can get a hard
>>> crash, but this appears to be the root cause.)
>>> 
>>> THANKS VERY MUCH FOR YOUR HELP.
>> 
>> Ok, here is what I gather from your traceback:
>> 
>> Your message object in {{ message }} is a LazyString instance from the 
>> speaklater library:
>> 
>> https://github.com/mitsuhiko/speaklater/blob/master/speaklater.py#L102
>> 
>> For some reason, this object does not have a _func attribute. Jinja 
>> calls its __unicode__ method, which access the `value` property, which 
>> access the `_func` attribute. Since the attribute is missing, this calls 
>> __getattr__ which calls the `value` property which access the `_func` 
>> attribute …
>> 
>> After a while, you hit the recursion limit. I don’t know why you get a 
>> "hard crash" (whatever that is) rather than a proper traceback but meh.
>> 
>> Now, how did we get this object with a missing attribute? Apparently it 
>> went through a session, which I think default to pickling. The 
>> __getstate__ and __setstate__ should cover this, and they look fine.
>> 
>> First, please check which version of speaklater you are running. Is it 
>> the same as the git master I’m looking at?
>> 
>> Then, make a _LazyString object with lazy_gettext(). Try to access its 
>> `value` property:
>> 
>> * Immediately
>> * After the object has gone through pickling and un-pickling using the 
>> pickle module from the standard library.
>> * After it has be serialized and serialized in a Flask session
>> 
>> Please report which work or not. Also, at each point, try this:
>> object.__getattribute__(the_lazystring_object, 'value')
>> 
>> The goal is to find at which point something goes wrong.
>> 
>> Good luck,
>> -- 
>> Simon Sapin
> 
> 

Re: [flask] Hard Flask Crash

From:
Jonathan Zempel
Date:
2012-06-22 @ 20:53
Ha - found it (sorry, Clayton :-). Here's a simplified gist that shows the
issue happens when '_kwargs' is dereferenced on a pickled LazyString.

Looks like Armin hasn't rolled this commit (

https://github.com/mitsuhiko/speaklater/commit/3ae4bf3083168da6f287acd27522d816ee5bdba1)
into the latest speaklater on PyPI.

When I add _kwargs to getstate/setstate, things work like they should.

Armin, can you release an updated speaklater? Until then, I guess we can
deploy the version from github.

Cheers,
Jonathan.

On Fri, Jun 22, 2012 at 1:37 PM, Clayton Cafiero <
clayton.cafiero@mondaylambson.com> wrote:

> Jonathan:
>
> Dang. You beat me to it.
>
> Excellent.
>
> I'll take a look at your test and see if I can make sense of it.
>
> Perhaps Simon can divine the cause.
> *
>
> Thanks!
>
> -Clayton
>
> *
>
> On 2012-06-22, at 04:29 PM, Jonathan Zempel wrote:
>
> Clayton,
>
> Thanks for pursuing this long-standing issue. I've worked-up the test that
> Simon suggested. https://gist.github.com/2974967
>
> The "max recursion" exception happens when 'value' is dereferenced on a
> pickled _LazyString (either standard pickle or via Flask session).
>
> I haven't yet dug into answering "why".
>
> Jonathan.
>
> On Thu, Jun 21, 2012 at 2:44 PM, Clayton Cafiero <
> clayton.cafiero@mondaylambson.com> wrote:
>
>> Simon:
>>
>> Thanks for the help. I'm using speaklater 1.2 and will work up a test
>> that checks the value property of the _LazyString object as you suggest.
>> Will report back soon.
>>
>> Thanks again,
>>
>> -Clayton
>>
>>
>>
>> On 2012-06-21, at 05:24 PM, Simon Sapin wrote:
>>
>> Le 21/06/2012 23:02, Clayton Cafiero a écrit :
>>
>> Hi Simon.
>>
>>
>> I've pared things down a bit for readability. You can view a test (based
>>
>> largely on Jonathan Zempel's test, posted earlier) and a traceback at
>>
>> https://gist.github.com/2968483. Bottom line (literally) is
>>
>> "RuntimeError: maximum recursion depth exceeded". Should one expect this
>>
>> result when using lazy_gettext? Again, this occurs when using
>>
>> lazy_gettext() to supply a message to flash() and then calling
>>
>> redirect(). Odd. (If we toss sessions into the mix we can get a hard
>>
>> crash, but this appears to be the root cause.)
>>
>>
>> THANKS VERY MUCH FOR YOUR HELP.
>>
>>
>> Ok, here is what I gather from your traceback:
>>
>> Your message object in {{ message }} is a LazyString instance from the
>> speaklater library:
>>
>> https://github.com/mitsuhiko/speaklater/blob/master/speaklater.py#L102
>>
>> For some reason, this object does not have a _func attribute. Jinja
>> calls its __unicode__ method, which access the `value` property, which
>> access the `_func` attribute. Since the attribute is missing, this calls
>> __getattr__ which calls the `value` property which access the `_func`
>> attribute …
>>
>> After a while, you hit the recursion limit. I don’t know why you get a
>> "hard crash" (whatever that is) rather than a proper traceback but meh.
>>
>> Now, how did we get this object with a missing attribute? Apparently it
>> went through a session, which I think default to pickling. The
>> __getstate__ and __setstate__ should cover this, and they look fine.
>>
>> First, please check which version of speaklater you are running. Is it
>> the same as the git master I’m looking at?
>>
>> Then, make a _LazyString object with lazy_gettext(). Try to access its
>> `value` property:
>>
>> * Immediately
>> * After the object has gone through pickling and un-pickling using the
>> pickle module from the standard library.
>> * After it has be serialized and serialized in a Flask session
>>
>> Please report which work or not. Also, at each point, try this:
>> object.__getattribute__(the_lazystring_object, 'value')
>>
>> The goal is to find at which point something goes wrong.
>>
>> Good luck,
>> --
>> Simon Sapin
>>
>>
>>
>
>

Re: [flask] Hard Flask Crash

From:
Clayton Cafiero
Date:
2012-06-22 @ 20:58
Hey Jonathan, you're too fast for me. But I'm glad somebody found it!

Thanks a million!


On 2012-06-22, at 04:53 PM, Jonathan Zempel wrote:

> Ha - found it (sorry, Clayton :-). Here's a simplified gist that shows 
the issue happens when '_kwargs' is dereferenced on a pickled LazyString.
> 
> Looks like Armin hasn't rolled this commit 
(https://github.com/mitsuhiko/speaklater/commit/3ae4bf3083168da6f287acd27522d816ee5bdba1)
into the latest speaklater on PyPI.
> 
> When I add _kwargs to getstate/setstate, things work like they should.
> 
> Armin, can you release an updated speaklater? Until then, I guess we can
deploy the version from github.
> 
> Cheers,
> Jonathan.
> 
> On Fri, Jun 22, 2012 at 1:37 PM, Clayton Cafiero 
<clayton.cafiero@mondaylambson.com> wrote:
> Jonathan:
> 
> Dang. You beat me to it.
> 
> Excellent.
> 
> I'll take a look at your test and see if I can make sense of it. 
> 
> Perhaps Simon can divine the cause.
> 
> Thanks!
> 
> -Clayton
> 
> 
> On 2012-06-22, at 04:29 PM, Jonathan Zempel wrote:
> 
>> Clayton,
>> 
>> Thanks for pursuing this long-standing issue. I've worked-up the test 
that Simon suggested. https://gist.github.com/2974967
>> 
>> The "max recursion" exception happens when 'value' is dereferenced on a
pickled _LazyString (either standard pickle or via Flask session).
>> 
>> I haven't yet dug into answering "why".
>> 
>> Jonathan.
>> 
>> On Thu, Jun 21, 2012 at 2:44 PM, Clayton Cafiero 
<clayton.cafiero@mondaylambson.com> wrote:
>> Simon:
>> 
>> Thanks for the help. I'm using speaklater 1.2 and will work up a test 
that checks the value property of the _LazyString object as you suggest. 
Will report back soon.
>> 
>> Thanks again,
>> 
>> -Clayton
>> 
>> 
>> 
>> On 2012-06-21, at 05:24 PM, Simon Sapin wrote:
>> 
>>> Le 21/06/2012 23:02, Clayton Cafiero a écrit :
>>>> Hi Simon.
>>>> 
>>>> I've pared things down a bit for readability. You can view a test (based
>>>> largely on Jonathan Zempel's test, posted earlier) and a traceback at
>>>> https://gist.github.com/2968483. Bottom line (literally) is
>>>> "RuntimeError: maximum recursion depth exceeded". Should one expect this
>>>> result when using lazy_gettext? Again, this occurs when using
>>>> lazy_gettext() to supply a message to flash() and then calling
>>>> redirect(). Odd. (If we toss sessions into the mix we can get a hard
>>>> crash, but this appears to be the root cause.)
>>>> 
>>>> THANKS VERY MUCH FOR YOUR HELP.
>>> 
>>> Ok, here is what I gather from your traceback:
>>> 
>>> Your message object in {{ message }} is a LazyString instance from the 
>>> speaklater library:
>>> 
>>> https://github.com/mitsuhiko/speaklater/blob/master/speaklater.py#L102
>>> 
>>> For some reason, this object does not have a _func attribute. Jinja 
>>> calls its __unicode__ method, which access the `value` property, which 
>>> access the `_func` attribute. Since the attribute is missing, this calls 
>>> __getattr__ which calls the `value` property which access the `_func` 
>>> attribute …
>>> 
>>> After a while, you hit the recursion limit. I don’t know why you get a 
>>> "hard crash" (whatever that is) rather than a proper traceback but meh.
>>> 
>>> Now, how did we get this object with a missing attribute? Apparently it 
>>> went through a session, which I think default to pickling. The 
>>> __getstate__ and __setstate__ should cover this, and they look fine.
>>> 
>>> First, please check which version of speaklater you are running. Is it 
>>> the same as the git master I’m looking at?
>>> 
>>> Then, make a _LazyString object with lazy_gettext(). Try to access its 
>>> `value` property:
>>> 
>>> * Immediately
>>> * After the object has gone through pickling and un-pickling using the 
>>> pickle module from the standard library.
>>> * After it has be serialized and serialized in a Flask session
>>> 
>>> Please report which work or not. Also, at each point, try this:
>>> object.__getattribute__(the_lazystring_object, 'value')
>>> 
>>> The goal is to find at which point something goes wrong.
>>> 
>>> Good luck,
>>> -- 
>>> Simon Sapin
>> 
>> 
> 
> 

Re: [flask] Hard Flask Crash

From:
Jonathan Zempel
Date:
2012-06-22 @ 21:22
np. I guess I'm too fast for me, too. Here's the missing link to that
simplified gist for creating the problem against (PyPI) speaklater 1.2:
https://gist.github.com/2975074

On Fri, Jun 22, 2012 at 1:58 PM, Clayton Cafiero <
clayton.cafiero@mondaylambson.com> wrote:

> Hey Jonathan, you're too fast for me. But I'm glad somebody found it!
>
> Thanks a million!
>
>
> On 2012-06-22, at 04:53 PM, Jonathan Zempel wrote:
>
> Ha - found it (sorry, Clayton :-). Here's a simplified gist that shows the
> issue happens when '_kwargs' is dereferenced on a pickled LazyString.
>
> Looks like Armin hasn't rolled this commit (
> 
https://github.com/mitsuhiko/speaklater/commit/3ae4bf3083168da6f287acd27522d816ee5bdba1)
> into the latest speaklater on PyPI.
>
> When I add _kwargs to getstate/setstate, things work like they should.
>
> Armin, can you release an updated speaklater? Until then, I guess we can
> deploy the version from github.
>
> Cheers,
> Jonathan.
>
> On Fri, Jun 22, 2012 at 1:37 PM, Clayton Cafiero <
> clayton.cafiero@mondaylambson.com> wrote:
>
>> Jonathan:
>>
>> Dang. You beat me to it.
>>
>> Excellent.
>>
>> I'll take a look at your test and see if I can make sense of it.
>>
>> Perhaps Simon can divine the cause.
>>   *
>>
>> Thanks!
>>
>> -Clayton
>>
>> *
>>
>> On 2012-06-22, at 04:29 PM, Jonathan Zempel wrote:
>>
>> Clayton,
>>
>> Thanks for pursuing this long-standing issue. I've worked-up the test
>> that Simon suggested. https://gist.github.com/2974967
>>
>> The "max recursion" exception happens when 'value' is dereferenced on a
>> pickled _LazyString (either standard pickle or via Flask session).
>>
>> I haven't yet dug into answering "why".
>>
>> Jonathan.
>>
>> On Thu, Jun 21, 2012 at 2:44 PM, Clayton Cafiero <
>> clayton.cafiero@mondaylambson.com> wrote:
>>
>>> Simon:
>>>
>>> Thanks for the help. I'm using speaklater 1.2 and will work up a test
>>> that checks the value property of the _LazyString object as you suggest.
>>> Will report back soon.
>>>
>>> Thanks again,
>>>
>>> -Clayton
>>>
>>>
>>>
>>> On 2012-06-21, at 05:24 PM, Simon Sapin wrote:
>>>
>>> Le 21/06/2012 23:02, Clayton Cafiero a écrit :
>>>
>>> Hi Simon.
>>>
>>>
>>> I've pared things down a bit for readability. You can view a test (based
>>>
>>> largely on Jonathan Zempel's test, posted earlier) and a traceback at
>>>
>>> https://gist.github.com/2968483. Bottom line (literally) is
>>>
>>> "RuntimeError: maximum recursion depth exceeded". Should one expect this
>>>
>>> result when using lazy_gettext? Again, this occurs when using
>>>
>>> lazy_gettext() to supply a message to flash() and then calling
>>>
>>> redirect(). Odd. (If we toss sessions into the mix we can get a hard
>>>
>>> crash, but this appears to be the root cause.)
>>>
>>>
>>> THANKS VERY MUCH FOR YOUR HELP.
>>>
>>>
>>> Ok, here is what I gather from your traceback:
>>>
>>> Your message object in {{ message }} is a LazyString instance from the
>>> speaklater library:
>>>
>>> https://github.com/mitsuhiko/speaklater/blob/master/speaklater.py#L102
>>>
>>> For some reason, this object does not have a _func attribute. Jinja
>>> calls its __unicode__ method, which access the `value` property, which
>>> access the `_func` attribute. Since the attribute is missing, this calls
>>> __getattr__ which calls the `value` property which access the `_func`
>>> attribute …
>>>
>>> After a while, you hit the recursion limit. I don’t know why you get a
>>> "hard crash" (whatever that is) rather than a proper traceback but meh.
>>>
>>> Now, how did we get this object with a missing attribute? Apparently it
>>> went through a session, which I think default to pickling. The
>>> __getstate__ and __setstate__ should cover this, and they look fine.
>>>
>>> First, please check which version of speaklater you are running. Is it
>>> the same as the git master I’m looking at?
>>>
>>> Then, make a _LazyString object with lazy_gettext(). Try to access its
>>> `value` property:
>>>
>>> * Immediately
>>> * After the object has gone through pickling and un-pickling using the
>>> pickle module from the standard library.
>>> * After it has be serialized and serialized in a Flask session
>>>
>>> Please report which work or not. Also, at each point, try this:
>>> object.__getattribute__(the_lazystring_object, 'value')
>>>
>>> The goal is to find at which point something goes wrong.
>>>
>>> Good luck,
>>> --
>>> Simon Sapin
>>>
>>>
>>>
>>
>>
>
>

Re: [flask] Hard Flask Crash

From:
Simon Sapin
Date:
2012-06-23 @ 00:52
Hi,

Congrats for debugging this!

I commented on the issue, this should ping Armin:
https://github.com/mitsuhiko/speaklater/issues/1

Regards,
-- 
Simon Sapin