import osimport subprocessimport sysimport threadingimport timefrom itertools import chainfrom ._compat import iteritemsfrom ._compat import PY2from ._compat import text_typefrom ._internal import _logdef _iter_module_files():"""This iterates over all relevant Python files. It goes through allloaded files from modules, all files in folders of already loaded modulesas well as all files reachable through a package."""# The list call is necessary on Python 3 in case the module# dictionary modifies during iteration.for module in list(sys.modules.values()):if module is None:continuefilename = getattr(module, "__file__", None)if filename:if os.path.isdir(filename) and os.path.exists(os.path.join(filename, "__init__.py")):filename = os.path.join(filename, "__init__.py")old = Nonewhile not os.path.isfile(filename):old = filenamefilename = os.path.dirname(filename)if filename == old:breakelse:if filename[-4:] in (".pyc", ".pyo"):filename = filename[:-1]yield filenamedef _find_observable_paths(extra_files=None):"""Finds all paths that should be observed."""rv = set(os.path.dirname(os.path.abspath(x)) if os.path.isfile(x) else os.path.abspath(x)for x in sys.path)for filename in extra_files or ():rv.add(os.path.dirname(os.path.abspath(filename)))for module in list(sys.modules.values()):fn = getattr(module, "__file__", None)if fn is None:continuefn = os.path.abspath(fn)rv.add(os.path.dirname(fn))return _find_common_roots(rv)def _get_args_for_reloading():"""Determine how the script was executed, and return the args neededto execute it again in a new process."""rv = [sys.executable]py_script = sys.argv[0]args = sys.argv[1:]# Need to look at main module to determine how it was executed.__main__ = sys.modules["__main__"]# The value of __package__ indicates how Python was called. It may# not exist if a setuptools script is installed as an egg. It may be# set incorrectly for entry points created with pip on Windows.if getattr(__main__, "__package__", None) is None or (os.name == "nt"and __main__.__package__ == ""and not os.path.exists(py_script)and os.path.exists(py_script + ".exe")):# Executed a file, like "python app.py".py_script = os.path.abspath(py_script)if os.name == "nt":# Windows entry points have ".exe" extension and should be# called directly.if not os.path.exists(py_script) and os.path.exists(py_script + ".exe"):py_script += ".exe"if (os.path.splitext(sys.executable)[1] == ".exe"and os.path.splitext(py_script)[1] == ".exe"):rv.pop(0)rv.append(py_script)else:# Executed a module, like "python -m werkzeug.serving".if sys.argv[0] == "-m":# Flask works around previous behavior by putting# "-m flask" in sys.argv.# TODO remove this once Flask no longer misbehavesargs = sys.argvelse:if os.path.isfile(py_script):# Rewritten by Python from "-m script" to "/path/to/script.py".py_module = __main__.__package__name = os.path.splitext(os.path.basename(py_script))[0]if name != "__main__":py_module += "." + nameelse:# Incorrectly rewritten by pydevd debugger from "-m script" to "script".py_module = py_scriptrv.extend(("-m", py_module.lstrip(".")))rv.extend(args)return rvdef _find_common_roots(paths):"""Out of some paths it finds the common roots that need monitoring."""paths = [x.split(os.path.sep) for x in paths]root = {}for chunks in sorted(paths, key=len, reverse=True):node = rootfor chunk in chunks:node = node.setdefault(chunk, {})node.clear()rv = set()def _walk(node, path):for prefix, child in iteritems(node):_walk(child, path + (prefix,))if not node:rv.add("/".join(path))_walk(root, ())return rvclass ReloaderLoop(object):name = None# monkeypatched by testsuite. wrapping with `staticmethod` is required in# case time.sleep has been replaced by a non-c function (e.g. by# `eventlet.monkey_patch`) before we get here_sleep = staticmethod(time.sleep)def __init__(self, extra_files=None, interval=1):self.extra_files = set(os.path.abspath(x) for x in extra_files or ())self.interval = intervaldef run(self):passdef restart_with_reloader(self):"""Spawn a new Python interpreter with the same arguments as this one,but running the reloader thread."""while 1:_log("info", " * Restarting with %s" % self.name)args = _get_args_for_reloading()# 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:new_environ = {}for key, value in iteritems(os.environ):if isinstance(key, text_type):key = key.encode("iso-8859-1")if isinstance(value, text_type):value = value.encode("iso-8859-1")new_environ[key] = valueelse:new_environ = os.environ.copy()new_environ["WERKZEUG_RUN_MAIN"] = "true"exit_code = subprocess.call(args, env=new_environ, close_fds=False)if exit_code != 3:return exit_codedef trigger_reload(self, filename):self.log_reload(filename)sys.exit(3)def log_reload(self, filename):filename = os.path.abspath(filename)_log("info", " * Detected change in %r, reloading" % filename)class StatReloaderLoop(ReloaderLoop):name = "stat"def run(self):mtimes = {}while 1:for filename in chain(_iter_module_files(), self.extra_files):try:mtime = os.stat(filename).st_mtimeexcept OSError:continueold_time = mtimes.get(filename)if old_time is None:mtimes[filename] = mtimecontinueelif mtime > old_time:self.trigger_reload(filename)self._sleep(self.interval)class WatchdogReloaderLoop(ReloaderLoop):def __init__(self, *args, **kwargs):ReloaderLoop.__init__(self, *args, **kwargs)from watchdog.observers import Observerfrom watchdog.events import FileSystemEventHandlerself.observable_paths = set()def _check_modification(filename):if filename in self.extra_files:self.trigger_reload(filename)dirname = os.path.dirname(filename)if dirname.startswith(tuple(self.observable_paths)):if filename.endswith((".pyc", ".pyo", ".py")):self.trigger_reload(filename)class _CustomHandler(FileSystemEventHandler):def on_created(self, event):_check_modification(event.src_path)def on_modified(self, event):_check_modification(event.src_path)def on_moved(self, event):_check_modification(event.src_path)_check_modification(event.dest_path)def on_deleted(self, event):_check_modification(event.src_path)reloader_name = Observer.__name__.lower()if reloader_name.endswith("observer"):reloader_name = reloader_name[:-8]reloader_name += " reloader"self.name = reloader_nameself.observer_class = Observerself.event_handler = _CustomHandler()self.should_reload = Falsedef trigger_reload(self, filename):# This is called inside an event handler, which means throwing# SystemExit has no effect.# https://github.com/gorakhargosh/watchdog/issues/294self.should_reload = Trueself.log_reload(filename)def run(self):watches = {}observer = self.observer_class()observer.start()try:while not self.should_reload:to_delete = set(watches)paths = _find_observable_paths(self.extra_files)for path in paths:if path not in watches:try:watches[path] = observer.schedule(self.event_handler, path, recursive=True)except OSError:# Clear this path from list of watches We don't want# the same error message showing again in the next# iteration.watches[path] = Noneto_delete.discard(path)for path in to_delete:watch = watches.pop(path, None)if watch is not None:observer.unschedule(watch)self.observable_paths = pathsself._sleep(self.interval)finally:observer.stop()observer.join()sys.exit(3)reloader_loops = {"stat": StatReloaderLoop, "watchdog": WatchdogReloaderLoop}try:__import__("watchdog.observers")except ImportError:reloader_loops["auto"] = reloader_loops["stat"]else:reloader_loops["auto"] = reloader_loops["watchdog"]def ensure_echo_on():"""Ensure that echo mode is enabled. Some tools such as PDB disableit which causes usability issues after reload."""# tcgetattr will fail if stdin isn't a ttyif not sys.stdin.isatty():returntry:import termiosexcept ImportError:returnattributes = termios.tcgetattr(sys.stdin)if not attributes[3] & termios.ECHO:attributes[3] |= termios.ECHOtermios.tcsetattr(sys.stdin, termios.TCSANOW, attributes)def run_with_reloader(main_func, extra_files=None, interval=1, reloader_type="auto"):"""Run the given function in an independent python interpreter."""import signalreloader = reloader_loops[reloader_type](extra_files, interval)signal.signal(signal.SIGTERM, lambda *args: sys.exit(0))try:if os.environ.get("WERKZEUG_RUN_MAIN") == "true":ensure_echo_on()t = threading.Thread(target=main_func, args=())t.setDaemon(True)t.start()reloader.run()else:sys.exit(reloader.restart_with_reloader())except KeyboardInterrupt:pass
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。