bottlepy / bottle

bottle.py is a fast and simple micro-framework for python web-applications.
http://bottlepy.org/
MIT License
8.4k stars 1.46k forks source link

Unicode issue with Python 2.7, WTForms and SimpleTemplate #364

Open baldman opened 12 years ago

baldman commented 12 years ago

Hello,

stumbled upon problem with above mentioned tools and cannot get to output field label defined in a form using the simple template engine.

Lets have simple form defined as such (WTForms):

    class UserLoginForm(Form):
        email = StringField('Uživatelske jmeno (email)', 
                                       [validators.Required(), validators.Email()])
        password = PasswordField('Heslo', [validators.Required()])

Notice the labels use national characters (prepending the string with 'u' doesn't help). Then in my template, I would have something along these lines:

<form method="post" action="/user/login" >
  {{! form.email.label }}
  {{! form.email }}

  {{! form.password.label }}    
  {{! form.password }}
  <input type="submit" />
</form>

Running this example, bottle will throw:

UnicodeEncodeError: 'ascii' codec can't encode characters in position 52-54: ordinal not in range(128)

No processing is done in between apart from instantiating the form and passing it to the template. Any suggestions as to how to solve this issue?

baldman commented 12 years ago

Oh one more thing, same problem occurs if I pass any unicode string as default value for the form fields, eg:

@view('my_template')
def myView():
   form = UserLoginForm(email=u'ěščřžý')
   return {"form": form}
defnull commented 12 years ago

It took a while, but I found it :)

form.email and form.email.label are neither byte nor unicode strings. Bottle tries to convert them and fails.

Try changing the hidden _str() function in your template:

% _str = unicode

This should work for your use-case, but in turn breaks {{some_int}} and other types that are not supported by unicode().

I'll keep this bug open until we find a better solution.

baldman commented 12 years ago

Ok great, I actually got to the same conclusion. And should anyone stumble upon this as well, be sure that the string you're passing to the field constructor is actually unicode object, otherwise, Bottle will throw different exception.

I will try to get around to devising a solution, if time allows.

defnull commented 12 years ago

Any magic-catch-all solution I could think of would really harm performance. It is probably best to throw helpful errors when someone tries to use incompatible objects in {{...}} statements.