)
parser.disable_interspersed_args()
parser.add_option("-m", dest="module", metavar="module", help="module to run")
+ parser.add_option(
+ "--until-success",
+ action="store_true",
+ help="stop reloading after the program exist successfully (status code 0)",
+ )
opts, rest = parser.parse_args()
if opts.module is None:
if not rest:
path = None
sys.argv = [sys.argv[0]] + rest
+ exit_status = 1
try:
import runpy
assert path is not None
runpy.run_path(path, run_name="__main__")
except SystemExit as e:
+ exit_status = e.code
gen_log.info("Script exited with status %s", e.code)
except Exception as e:
gen_log.warning("Script exited with uncaught exception", exc_info=True)
if e.filename is not None:
watch(e.filename)
else:
+ exit_status = 0
gen_log.info("Script exited normally")
# restore sys.argv so subsequent executions will include autoreload
sys.argv = original_argv
if loader is not None:
watch(loader.get_filename()) # type: ignore
+ if opts.until_success and exit_status == 0:
+ return
wait()
self.path = mkdtemp()
- # Each test app runs itself twice via autoreload. The first time it manually triggers
+ # Most test apps run themselves twice via autoreload. The first time it manually triggers
# a reload (could also do this by touching a file but this is faster since filesystem
# timestamps are not necessarily high resolution). The second time it exits directly
# so that the autoreload wrapper (if it is used) doesn't catch it.
#
- # The last line of each test's "main" program should be
+ # The last line of each such test's "main" program should be
# exec(open("run_twice_magic.py").read())
self.write_files(
{
)
self.assertEqual(out, "main.py\nargv=['arg1', '--arg2', '-m', 'arg3']\n" * 2)
+
+ def test_reload_wrapper_until_success(self):
+ main = """\
+import os
+import sys
+
+if "TESTAPP_STARTED" in os.environ:
+ print("exiting cleanly")
+ sys.exit(0)
+else:
+ print("reloading")
+ exec(open("run_twice_magic.py").read())
+"""
+
+ # Create temporary test application
+ self.write_files({"main.py": main})
+
+ out = self.run_subprocess(
+ [sys.executable, "-m", "tornado.autoreload", "--until-success", "main.py"]
+ )
+
+ self.assertEqual(out, "reloading\nexiting cleanly\n")