在 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:Python27libsite-packagesflaskapp.py", line 943, in run run_simple(host, port, self, **options) File "D:Python27libsite-packageswerkzeugserving.py", line 812, in run_simple reloader_type) File "D:Python27libsite-packageswerkzeug\_reloader.py", line 275, in run_with_reloader sys.exit(reloader.restart_with_reloader()) File "D:Python27libsite-packageswerkzeug\_reloader.py", line 132, in restart_with_reloader close_fds=False) File "D:Python27libsubprocess.py", line 172, in call return Popen(*popenargs, **kwargs).wait() File "D:Python27libsubprocess.py", line 394, in __init__ errread, errwrite) File "D:Python27libsubprocess.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)