From: Ben Darnell Date: Tue, 6 Mar 2012 07:25:06 +0000 (-0800) Subject: One more autoreload path tweak: set $PYTHONPATH just before exec, X-Git-Tag: v2.3.0~69 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=bcbef8c72046e7fc1a50e97b99a2716d546191f5;p=thirdparty%2Ftornado.git One more autoreload path tweak: set $PYTHONPATH just before exec, whether autoreload is __main__ or not. --- diff --git a/tornado/autoreload.py b/tornado/autoreload.py index 84975067d..5baae0de3 100644 --- a/tornado/autoreload.py +++ b/tornado/autoreload.py @@ -31,28 +31,33 @@ from __future__ import absolute_import, division, with_statement import os import sys +# sys.path handling +# ----------------- +# +# If a module is run with "python -m", the current directory (i.e. "") +# is automatically prepended to sys.path, but not if it is run as +# "path/to/file.py". The processing for "-m" rewrites the former to +# the latter, so subsequent executions won't have the same path as the +# original. +# +# Conversely, when run as path/to/file.py, the directory containing +# file.py gets added to the path, which can cause confusion as imports +# may become relative in spite of the future import. +# +# We address the former problem by setting the $PYTHONPATH environment +# variable before re-execution so the new process will see the correct +# path. We attempt to address the latter problem when tornado.autoreload +# is run as __main__, although we can't fix the general case because +# we cannot reliably reconstruct the original command line +# (http://bugs.python.org/issue14208). + if __name__ == "__main__": - # If this module is run with "python -m tornado.autoreload", the current - # directory is automatically prepended to sys.path, but not if it is - # run as "path/to/tornado/autoreload.py". The processing for "-m" rewrites - # the former to the latter, so subsequent executions won't have the same - # path as the original. Modify os.environ here to ensure that the - # re-executed process will have the same path. - # - # Conversely, when run as path/to/tornado/autoreload.py, the directory - # containing autoreload.py gets added to the path, but we don't want - # tornado modules importable at top level, so remove it. - # # This sys.path manipulation must come before our imports (as much # as possible - if we introduced a tornado.sys or tornado.os # module we'd be in trouble), or else our imports would become # relative again despite the future import. # # There is a separate __main__ block at the end of the file to call main(). - path_prefix = '.' + os.pathsep - if (sys.path[0] == '' and - not os.environ.get("PYTHONPATH", "").startswith(path_prefix)): - os.environ["PYTHONPATH"] = path_prefix + os.environ.get("PYTHONPATH", "") if sys.path[0] == os.path.dirname(__file__): del sys.path[0] @@ -181,6 +186,15 @@ def _reload(): # ioloop.set_blocking_log_threshold so it doesn't fire # after the exec. signal.setitimer(signal.ITIMER_REAL, 0, 0) + # sys.path fixes: see comments at top of file. If sys.path[0] is an empty + # string, we were (probably) invoked with -m and the effective path + # is about to change on re-exec. Add the current directory to $PYTHONPATH + # to ensure that the new process sees the same path we did. + path_prefix = '.' + os.pathsep + if (sys.path[0] == '' and + not os.environ.get("PYTHONPATH", "").startswith(path_prefix)): + os.environ["PYTHONPATH"] = (path_prefix + + os.environ.get("PYTHONPATH", "")) if sys.platform == 'win32': # os.execv is broken on Windows and can't properly parse command line # arguments and executable name if they contain whitespaces. subprocess