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]
# 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