1. 程式人生 > >解決 Flask 專案無法用 .env 檔案中解析的引數設定環境變數的錯誤

解決 Flask 專案無法用 .env 檔案中解析的引數設定環境變數的錯誤

在 Windows 上啟動 Flask 專案時,工作目錄有 UTF-8 編碼的 .env 檔案,裡面配置的環境變數在 Python2 中識別為 Unicode 型別,導致下述錯誤:

 * Serving Flask app "bootstrap" (lazy loading)
 * Environment: development
 * Debug mode: on
 * Restarting with stat
Traceback (most recent call last):
  File "bootstrap.py", line 40, in <module>
    app.run(host=str(settings.DEV_HOST), port=settings.DEV_PORT)
  File "D:\Python27\lib\site-packages\flask\app.py", line 943, in run
    run_simple(host, port, self, **options)
  File "D:\Python27\lib\site-packages\werkzeug\serving.py", line 812, in run_simple
    reloader_type)
  File "D:\Python27\lib\site-packages\werkzeug\_reloader.py", line 275, in run_with_reloader
    sys.exit(reloader.restart_with_reloader())
  File "D:\Python27\lib\site-packages\werkzeug\_reloader.py", line 132, in restart_with_reloader
    close_fds=False)
  File "D:\Python27\lib\subprocess.py", line 172, in call
    return Popen(*popenargs, **kwargs).wait()
  File "D:\Python27\lib\subprocess.py", line 394, in __init__
    errread, errwrite)
  File "D:\Python27\lib\subprocess.py", line 644, in _execute_child
    startupinfo)
TypeError: environment can only contain strings

遇到這種情況,只需對 werkzeug 專案做個小的修改即可。Diff 檔案如下所示:

diff --git a/werkzeug/_reloader.backup.py b/werkzeug/_reloader.py
# index 0d23dba..2698040 100644
# --- a/_reloader.backup.py
# +++ b/_reloader.py
# @@ -117,16 +117,20 @@ class ReloaderLoop(object):
#          while 1:
#              _log('info', ' * Restarting with %s' % self.name)
#              args = _get_args_for_reloading()
# -            new_environ = os.environ.copy()
# -            new_environ['WERKZEUG_RUN_MAIN'] = 'true'
# +            old_environ = os.environ.copy()
# +            new_environ = {
# +                'WERKZEUG_RUN_MAIN': 'true'
# +            }
# 
#              # a weird bug on windows. sometimes unicode strings end up in the
#              # environment and subprocess.call does not like this, encode them
#              # to latin1 and continue.
#              if os.name == 'nt' and PY2:
# -                for key, value in iteritems(new_environ):
# +                for key, value in iteritems(old_environ):
#                      if isinstance(value, text_type):
# -                        new_environ[key] = value.encode('iso-8859-1')
# +                        new_environ[key.encode('iso-8859-1')] = value.encode('iso-8859-1')
# +                    else:
# +                        new_environ[key] = value
# 
#              exit_code = subprocess.call(args, env=new_environ,
#                                          close_fds=False)