This one has been torturing me for a while. Here is how to replicate
it consistently (and possibly fix it):

1. Create a brand new application (in my case named 'ttt')
2. In db.py say "auth.settings.expiration=10" (so sessions expire
quick)
3. In the default controller create a new function:

@auth.requires_login()
def frm():
    form = SQLFORM.factory( Field('email', requires=
IS_EMAIL(error_message=auth.messages.invalid_email)))
    return dict(form=form)

4. Register a user (in my case i...@gmail.com)
5. Login with your new user and visit http://localhost/ttt/default/frm/
6. Let session expire (wait 10s)
7. In the form 'email' field enter 'i...@gmail.com' and hit 'Submit'
8. You get:

Traceback (most recent call last):
  File "/pub/web2py/gluon/restricted.py", line 194, in restricted
    exec ccode in environment
  File "/pub/web2py/applications/ttt/controllers/default.py", line 75,
in <module>
  File "/pub/web2py/gluon/globals.py", line 149, in <lambda>
    self._caller = lambda f: f()
  File "/pub/web2py/applications/ttt/controllers/default.py", line 37,
in user
    return dict(form=auth())
  File "/pub/web2py/gluon/tools.py", line 1126, in __call__
    return getattr(self,args[0])()
  File "/pub/web2py/gluon/tools.py", line 1726, in login
    next = replace_id(next, form)
  File "/pub/web2py/gluon/tools.py", line 79, in replace_id
    return url % form.vars
TypeError: float argument required, not Storage

So it tries to get back to:
http://localhost/ttt/default/user/login?_next=/ttt/default/frm%3Femail%3Diii%2540gmail.com

Inside replace_id(...):
url is '/ttt/default/frm?email=iii%40gmail.com'
form.vars is Storage({'password': '5638e85e6f35b0716e5ddac33a0',
'email': 'i...@gmail.com', 'remember': None})

Also try from the python console:
'/ttt/default/frm?email=iii%40gmail.com' % Storage({'password':
'5638e85e6f35b0716e5ddac33a0', 'email': 'i...@gmail.com', 'remember':
None})

Like Jim noted in the original post the '%' containing, URL escaped
symbols in 'url' coincide with Python's interpretation for a float.
Notice I don't have %2F in my string, here it looks like the '%40g' is
doing it.

A patch which seems to be fixing it is:

diff gluon/tools.py gluon/tools.py.patch
79c79
<         return url % form.vars
---
>         return urllib.unquote(url) % form.vars

but looking at the comment on gluon/tools.py:78 "this allows
http://..../%(id)s/%(name)s/etc." I have not tested with such URLs.

Running 1.99.2, BTW. Let me know if I can help further...

Reply via email to