2014年3月10日 星期一

GAE SDK Launcher 因 UnicodeDecodeError 無法運行問題

前幾天把老筆電重灌 XP 後, 發現效能變好了, 但做完 Ghost 才發現最新的 GAE SDK 1.9.0 版本機伺服器無法運行應用程式, 通常按下 Run 後前面就會出現一個播放中符號, 但這回卻出現驚嘆號三角形, 即使是預設的 Hello World 也無法運行.


原先以為是 1.9.0 版有問題, 但我的小筆電也是 SDK 1.9.0 版呀, 為何它就沒問題? 晚上下載舊版 1.8.9 安裝, 情況依舊. 在 DOS 視窗直接下指令啟動伺服器可看到其錯誤訊息為 :

UnicodeDecodeError: 'ascii' codec can't decode byte 0xa4 in position 9: ordinal  not in range(128)

看不懂, 但似乎是編碼問題, 搜尋網路上資訊, 大都是英文, 主要是 Python 2 版預設編碼是 ASCII 之故, 看了幾篇還是沒解決. 晚上看到下列這篇, 真是有如神助, 原來是 Python 2.7 的問題, 只要將 C:\Python27\Lib\mimetypes.py 這個檔內的 UnicodeEncodingError 改為  UnicodeError (有兩筆, 在 250 與 272 行) 就可以了 :

# 雄 : Google App Engine 雜記

2015-12-29 補充 :
Python 2.7.11 與 GAE SDK 1.9.30 已經無此問題了.




我比對了一下小筆電裡的 path 設定, 發現了我的小筆電不敗的秘密, 原來它還是跑 Python2.5 版! 雖然已經安裝 Python 2.7.6, 而且 GAE SDK 也升版為 1.9.0, 所以不受影響 :

E:\GAE<path
PATH=C:\Ruby200\bin;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\Program Files\EgisTec MyWinLocker\x86;C:\Program Files\EgisTec MyWinLocker\x64;C:
\Program Files\Java\jdk1.7.0\bin;c:\python25;c:\python25\scripts;C:\Program Files\nodejs\;C:\AppServ\Apache2.2\bin;C:\AppServ\php5;C:\AppServ\MySQL\bin;C:\Documents and Settings\D26\Application Data\npm;C:\Program Files\Google\google_appengine\

要讓其跑 Python 2.7.6 版, 須修改環境變數的 path 設定, 改成 python27 即可. 其次打開 Python 2.7.6 版的 LIB\mimetypes.py, 在 229 行處有一個 read_windows_registry() 方法, 在 250 與 270 行各有一個 UnicodeEncodeError 的例外, 只要將其改為拋出 UnicodeError 例外即可. 這個讀取 Windows 註冊檔的方法在 Python 2.5 版的 mimetypes.py 裡沒有.

    def read_windows_registry(self, strict=True):
        """
        Load the MIME types database from Windows registry.

        If strict is true, information will be added to
        list of standard types, else to the list of non-standard
        types.
        """

        # Windows only
        if not _winreg:
            return

        def enum_types(mimedb):
            i = 0
            while True:
                try:
                    ctype = _winreg.EnumKey(mimedb, i)
                except EnvironmentError:
                    break
                try:
                    ctype = ctype.encode(default_encoding) # omit in 3.x!
                except UnicodeEncodeError:
                    pass
                else:
                    yield ctype
                i += 1

        default_encoding = sys.getdefaultencoding()
        with _winreg.OpenKey(_winreg.HKEY_CLASSES_ROOT,
                             r'MIME\Database\Content Type') as mimedb:
            for ctype in enum_types(mimedb):
                with _winreg.OpenKey(mimedb, ctype) as key:
                    try:
                        suffix, datatype = _winreg.QueryValueEx(key, 'Extension')
                    except EnvironmentError:
                        continue
                    if datatype != _winreg.REG_SZ:
                        continue
                    try:
                        suffix = suffix.encode(default_encoding) # omit in 3.x!
                    except UnicodeEncodeError:
                        continue
                    self.add_type(ctype, suffix, strict)

這樣我的小筆電就真的跑 Python 2.7.6 也沒問題了. 雄大哥真是太感謝您了! 要不然我只能用那台小筆電玩 GAE 了.


3 則留言:

  1. 您好:看了您的文章,非常感謝,但是後續又出了些問題
    IOError: [Errno 2] No usable temporary directory found in ['C:\\Users\\\xbcB\xae\xd1\xbb\xa8\\AppData\\Local\\Temp', 'C:\\Users\\\xbcB\xae\xd1\xbb\xa8\\AppData\\Local\\Temp', 'c:\\temp', 'c:\\tmp', '\\temp', '\\tmp', 'C:\\Program Files\\Google\\google_appengine\\launcher']

    是否可以請教您這是出了什麼問題呢!? 要如何解決,非常的謝謝您!!!

    回覆刪除
  2. 這我倒沒有遇過呢! 我把 pYTHON 從 2.5 升版為 2.7 後就只遇到上面這個問題而已, 可到 gOOGLE 找看看.

    回覆刪除