2012-07-11 33 views
1

背景:我是gae-boilerplate的主要貢獻者之一,這是一個開源的boilerplate項目,幫助用戶用webapp2和最新的特徵。我所研究的最新功能是i18n使用Babel和gaepytz,這是下面描述的問題所在。谷歌應用引擎與python webapp2 lazy_gettext錯誤babel

問題:翻譯與gettext一起工作,但翻譯在我們的處理程序和wtforms類中生成的表單錯誤消息,我需要lazy_gettext,據我所知。當我在handlers.py中調用from webapp2_extras.i18n import lazy_gettext as _時,Lazy_gettext不起作用。加載頁面時,我收到以下致命錯誤消息。看起來像Babel Lazy代理對象被創建,但是在谷歌應用引擎服務器代碼中被傳遞給json序列化程序之前,它們不會被調用來呈現本地化的字符串。我已經瀏覽了babel網站,webapp2文檔(我希望它更徹底),其他框架和一些谷歌代碼,但我一直無法弄清楚我錯過了什麼。

錯誤消息:

Traceback (most recent call last): 
File "C:\Program Files (x86)\Google\google_appengine\lib\webapp2\webapp2.py", line 1536, in __call__ 
    rv = self.handle_exception(request, response, e) 
File "C:\Program Files (x86)\Google\google_appengine\lib\webapp2\webapp2.py", line 1530, in __call__ 
    rv = self.router.dispatch(request, response) 
File "C:\Program Files (x86)\Google\google_appengine\lib\webapp2\webapp2.py", line 1278, in default_dispatcher 
    return route.handler_adapter(request, response) 
File "C:\Program Files (x86)\Google\google_appengine\lib\webapp2\webapp2.py", line 1102, in __call__ 
    return handler.dispatch() 
File "H:\jesse\python_dev\workspace\gae-boilerplate\lib\basehandler.py", line 54, in dispatch 
    self.session_store.save_sessions(self.response) 
File "C:\Program Files (x86)\Google\google_appengine\lib\webapp2\webapp2_extras\sessions.py", line 420, in save_sessions 
    session.save_session(response) 
File "C:\Program Files (x86)\Google\google_appengine\lib\webapp2\webapp2_extras\sessions.py", line 205, in save_session 
    response, self.name, dict(self.session), **self.session_args) 
File "C:\Program Files (x86)\Google\google_appengine\lib\webapp2\webapp2_extras\sessions.py", line 423, in save_secure_cookie 
    value = self.serializer.serialize(name, value) 
File "C:\Program Files (x86)\Google\google_appengine\lib\webapp2\webapp2_extras\securecookie.py", line 47, in serialize 
    value = self._encode(value) 
File "C:\Program Files (x86)\Google\google_appengine\lib\webapp2\webapp2_extras\securecookie.py", line 92, in _encode 
    return json.b64encode(value) 
File "C:\Program Files (x86)\Google\google_appengine\lib\webapp2\webapp2_extras\json.py", line 84, in b64encode 
    return base64.b64encode(encode(value, *args, **kwargs)) 
File "C:\Program Files (x86)\Google\google_appengine\lib\webapp2\webapp2_extras\json.py", line 55, in encode 
    return json.dumps(value, *args, **kwargs).replace("</", "<\\/") 
File "C:\Program Files (x86)\Google\google_appengine\lib\simplejson\simplejson\__init__.py", line 272, in dumps 
    use_decimal=use_decimal, **kw).encode(obj) 
File "C:\Program Files (x86)\Google\google_appengine\lib\simplejson\simplejson\encoder.py", line 216, in encode 
    chunks = list(chunks) 
File "C:\Program Files (x86)\Google\google_appengine\lib\simplejson\simplejson\encoder.py", line 485, in _iterencode 
    for chunk in _iterencode_dict(o, _current_indent_level): 
File "C:\Program Files (x86)\Google\google_appengine\lib\simplejson\simplejson\encoder.py", line 459, in _iterencode_dict 
    for chunk in chunks: 
File "C:\Program Files (x86)\Google\google_appengine\lib\simplejson\simplejson\encoder.py", line 380, in _iterencode_list 
    for chunk in chunks: 
File "C:\Program Files (x86)\Google\google_appengine\lib\simplejson\simplejson\encoder.py", line 380, in _iterencode_list 
    for chunk in chunks: 
File "C:\Program Files (x86)\Google\google_appengine\lib\simplejson\simplejson\encoder.py", line 495, in _iterencode 
    o = _default(o) 
File "C:\Program Files (x86)\Google\google_appengine\lib\simplejson\simplejson\encoder.py", line 190, in default 
    raise TypeError(repr(o) + " is not JSON serializable") 
TypeError: <babel.support.LazyProxy object at 0x00000000084E81F8> is not JSON serializable 

環境的詳細信息:關於蟒蛇,webapp2的,巴貝爾等版本的詳細信息可以通過向下滾動到readme at github.com/coto/gae-boilerplate被發現。我運行最新的谷歌應用程序引擎的SDK 1.7.0

如何重現

  1. https://github.com/coto/gae-boilerplate
  2. 下載代碼的Web更換from webapp2_extras.i18n import gettext as _/handlers.py與from webapp2_extras.i18n import lazy_gettext as _
  3. 使用應用引擎開發服務器運行(在https://developers.google.com/appengine/docs/python/tools/devserver處提供說明)
  4. 註冊或登錄然後註銷(localhost:8080/logout /)。註銷行爲將產生一條表明您已註銷的Flash消息,它將在註銷處理程序中使用lazy_gettext包裝消息生成錯誤,從而觸發錯誤。

任何幫助將不勝感激,並無疑會幫助該項目和webapp2的其他用戶。此外,如果您仔細查看github上的代碼,任何最佳實踐提示都將成爲獎勵。 謝謝!

回答

2

這真的很老,但也許別人有同樣的問題。

懶惰的gettext將翻譯過程包含在後面,所以它不是一個真正的字符串,而是一個不同類型的對象。有些json庫會檢查你試圖進行jsonify的表達式的類型,所以它會給你一個例外。要解決這個問題,你可以使用unicode builtin來觸發翻譯。

Ex。

a = lazy_gettext("wololoh") 
jsonify({'msg': a}) # this will throw an exception 
jsonify({'msg': unicode(a)}) # this should work correctly 

希望這是有用的

2

Babel有一個名爲LazyProxy的自定義類,它基本上只是封裝了一個函數,只有在它真的需要函數的返回值時纔會調用它。代理嘗試儘可能透明,但我假設simplejson檢查實際的類對象,這是它失敗的地方。

我不確定simplejson是否使用協議向實例的序列化版本請求未知類(然後我們可以在LazyProxy中實現該類)。

如果你可以以某種方式改變你的庫,你也可以爲LazyProxy實例創建一個自定義序列化器(這應該非常簡單)。另一個選擇是找到LazyProxy實例並使用'proxy.value'來獲取代理值(我認爲它是json-serializable)。

+0

真棒感謝。我會盡快給你一個機會,讓你知道它是如何發生的。 – peta15 2012-08-12 15:59:43

相關問題