We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
import collision between http.py and Python 3's http modules
Here is a (granted, obscure) way to reproduce this bug:
1. `cd` into the `werkzeug` directory (i.e. where `serving.py`, `http.py`, etc. are located).
2. start a Python interpreter
3. type `import test`. This works for Python 2.x, but in Python 3.x this is what happens:
   
   ```
   (venv34) werkzeug $ python
   Python 3.4.1 (default, Sep  6 2014, 18:06:58) 
   [GCC 4.8.2] on linux
   Type "help", "copyright", "credits" or "license" for more information.
   >>> import test
   Traceback (most recent call last):
     File "/home/miguel/Documents/dev/flask/werkzeug/werkzeug/test.py", line 20, in <module>
       from urllib2 import Request as U2Request
   ImportError: No module named 'urllib2'
   
   During handling of the above exception, another exception occurred:
   
   Traceback (most recent call last):
     File "/home/miguel/Documents/dev/flask/werkzeug/werkzeug/http.py", line 26, in <module>
       from urllib2 import parse_http_list as _parse_list_header
   ImportError: No module named 'urllib2'
   
   During handling of the above exception, another exception occurred:
   
   Traceback (most recent call last):
     File "<stdin>", line 1, in <module>
     File "/home/miguel/Documents/dev/flask/werkzeug/werkzeug/test.py", line 22, in <module>
       from urllib.request import Request as U2Request
     File "/opt/python3.4/lib/python3.4/urllib/request.py", line 88, in <module>
       import http.client
     File "/home/miguel/Documents/dev/flask/werkzeug/werkzeug/http.py", line 28, in <module>
       from urllib.request import parse_http_list as _parse_list_header
   ImportError: cannot import name 'parse_http_list'
   >>> 
   ```

The problem is that Python 3's reorg of `httplib` into `http.xxx` modules causes an import collision between `http.client` and werkzeug's `http.py`, and `http.py` wins because its directory is in `sys.path`.

I agree that the example above is pretty obscure and unlike to ever be a problem. A more likely example is when you start an application with the syntax `python -m werkzeug.serving -r module:app`. In this situation the process starts and then spawns a sub-process for the reloader. The sub-process is going to have the directory where `werkzeug.serving` is located in the `sys.path`, so the bug reproduces there as well.

Would you be open to rename `http.py`? Or do you have a better idea?


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `werkzeug/_reloader.py`
Content:
```
1 import os
2 import sys
3 import time
4 import subprocess
5 import threading
6 from itertools import chain
7 
8 from werkzeug._internal import _log
9 from werkzeug._compat import PY2, iteritems, text_type
10 
11 
12 def _iter_module_files():
13     """This iterates over all relevant Python files.  It goes through all
14     loaded files from modules, all files in folders of already loaded modules
15     as well as all files reachable through a package.
16     """
17     # The list call is necessary on Python 3 in case the module
18     # dictionary modifies during iteration.
19     for module in list(sys.modules.values()):
20         if module is None:
21             continue
22         filename = getattr(module, '__file__', None)
23         if filename:
24             if os.path.isdir(filename) and \
25                os.path.exists(os.path.join(filename, "__init__.py")):
26                 filename = os.path.join(filename, "__init__.py")
27 
28             old = None
29             while not os.path.isfile(filename):
30                 old = filename
31                 filename = os.path.dirname(filename)
32                 if filename == old:
33                     break
34             else:
35                 if filename[-4:] in ('.pyc', '.pyo'):
36                     filename = filename[:-1]
37                 yield filename
38 
39 
40 def _find_observable_paths(extra_files=None):
41     """Finds all paths that should be observed."""
42     rv = set(os.path.dirname(os.path.abspath(x))
43              if os.path.isfile(x) else os.path.abspath(x)
44              for x in sys.path)
45 
46     for filename in extra_files or ():
47         rv.add(os.path.dirname(os.path.abspath(filename)))
48 
49     for module in list(sys.modules.values()):
50         fn = getattr(module, '__file__', None)
51         if fn is None:
52             continue
53         fn = os.path.abspath(fn)
54         rv.add(os.path.dirname(fn))
55 
56     return _find_common_roots(rv)
57 
58 
59 def _get_args_for_reloading():
60     """Returns the executable. This contains a workaround for windows
61     if the executable is incorrectly reported to not have the .exe
62     extension which can cause bugs on reloading.  This also contains
63     a workaround for linux where the file is executable (possibly with
64     a program other than python)
65     """
66     rv = [sys.executable]
67     py_script = os.path.abspath(sys.argv[0])
68 
69     if os.name == 'nt' and not os.path.exists(py_script) and \
70        os.path.exists(py_script + '.exe'):
71         py_script += '.exe'
72 
73     windows_workaround = (
74         os.path.splitext(rv[0])[1] == '.exe'
75         and os.path.splitext(py_script)[1] == '.exe'
76     )
77     nix_workaround = os.path.isfile(py_script) and os.access(py_script, os.X_OK)
78 
79     if windows_workaround or nix_workaround:
80         rv.pop(0)
81 
82     rv.append(py_script)
83     rv.extend(sys.argv[1:])
84     return rv
85 
86 
87 def _find_common_roots(paths):
88     """Out of some paths it finds the common roots that need monitoring."""
89     paths = [x.split(os.path.sep) for x in paths]
90     root = {}
91     for chunks in sorted(paths, key=len, reverse=True):
92         node = root
93         for chunk in chunks:
94             node = node.setdefault(chunk, {})
95         node.clear()
96 
97     rv = set()
98 
99     def _walk(node, path):
100         for prefix, child in iteritems(node):
101             _walk(child, path + (prefix,))
102         if not node:
103             rv.add('/'.join(path))
104     _walk(root, ())
105     return rv
106 
107 
108 class ReloaderLoop(object):
109     name = None
110 
111     # monkeypatched by testsuite. wrapping with `staticmethod` is required in
112     # case time.sleep has been replaced by a non-c function (e.g. by
113     # `eventlet.monkey_patch`) before we get here
114     _sleep = staticmethod(time.sleep)
115 
116     def __init__(self, extra_files=None, interval=1):
117         self.extra_files = set(os.path.abspath(x)
118                                for x in extra_files or ())
119         self.interval = interval
120 
121     def run(self):
122         pass
123 
124     def restart_with_reloader(self):
125         """Spawn a new Python interpreter with the same arguments as this one,
126         but running the reloader thread.
127         """
128         while 1:
129             _log('info', ' * Restarting with %s' % self.name)
130             args = _get_args_for_reloading()
131 
132             # a weird bug on windows. sometimes unicode strings end up in the
133             # environment and subprocess.call does not like this, encode them
134             # to latin1 and continue.
135             if os.name == 'nt' and PY2:
136                 new_environ = {}
137                 for key, value in iteritems(os.environ):
138                     if isinstance(key, text_type):
139                         key = key.encode('iso-8859-1')
140                     if isinstance(value, text_type):
141                         value = value.encode('iso-8859-1')
142                     new_environ[key] = value
143             else:
144                 new_environ = os.environ.copy()
145 
146             new_environ['WERKZEUG_RUN_MAIN'] = 'true'
147             exit_code = subprocess.call(args, env=new_environ,
148                                         close_fds=False)
149             if exit_code != 3:
150                 return exit_code
151 
152     def trigger_reload(self, filename):
153         self.log_reload(filename)
154         sys.exit(3)
155 
156     def log_reload(self, filename):
157         filename = os.path.abspath(filename)
158         _log('info', ' * Detected change in %r, reloading' % filename)
159 
160 
161 class StatReloaderLoop(ReloaderLoop):
162     name = 'stat'
163 
164     def run(self):
165         mtimes = {}
166         while 1:
167             for filename in chain(_iter_module_files(),
168                                   self.extra_files):
169                 try:
170                     mtime = os.stat(filename).st_mtime
171                 except OSError:
172                     continue
173 
174                 old_time = mtimes.get(filename)
175                 if old_time is None:
176                     mtimes[filename] = mtime
177                     continue
178                 elif mtime > old_time:
179                     self.trigger_reload(filename)
180             self._sleep(self.interval)
181 
182 
183 class WatchdogReloaderLoop(ReloaderLoop):
184 
185     def __init__(self, *args, **kwargs):
186         ReloaderLoop.__init__(self, *args, **kwargs)
187         from watchdog.observers import Observer
188         from watchdog.events import FileSystemEventHandler
189         self.observable_paths = set()
190 
191         def _check_modification(filename):
192             if filename in self.extra_files:
193                 self.trigger_reload(filename)
194             dirname = os.path.dirname(filename)
195             if dirname.startswith(tuple(self.observable_paths)):
196                 if filename.endswith(('.pyc', '.pyo', '.py')):
197                     self.trigger_reload(filename)
198 
199         class _CustomHandler(FileSystemEventHandler):
200 
201             def on_created(self, event):
202                 _check_modification(event.src_path)
203 
204             def on_modified(self, event):
205                 _check_modification(event.src_path)
206 
207             def on_moved(self, event):
208                 _check_modification(event.src_path)
209                 _check_modification(event.dest_path)
210 
211             def on_deleted(self, event):
212                 _check_modification(event.src_path)
213 
214         reloader_name = Observer.__name__.lower()
215         if reloader_name.endswith('observer'):
216             reloader_name = reloader_name[:-8]
217         reloader_name += ' reloader'
218 
219         self.name = reloader_name
220 
221         self.observer_class = Observer
222         self.event_handler = _CustomHandler()
223         self.should_reload = False
224 
225     def trigger_reload(self, filename):
226         # This is called inside an event handler, which means throwing
227         # SystemExit has no effect.
228         # https://github.com/gorakhargosh/watchdog/issues/294
229         self.should_reload = True
230         self.log_reload(filename)
231 
232     def run(self):
233         watches = {}
234         observer = self.observer_class()
235         observer.start()
236 
237         try:
238             while not self.should_reload:
239                 to_delete = set(watches)
240                 paths = _find_observable_paths(self.extra_files)
241                 for path in paths:
242                     if path not in watches:
243                         try:
244                             watches[path] = observer.schedule(
245                                 self.event_handler, path, recursive=True)
246                         except OSError:
247                             # Clear this path from list of watches We don't want
248                             # the same error message showing again in the next
249                             # iteration.
250                             watches[path] = None
251                     to_delete.discard(path)
252                 for path in to_delete:
253                     watch = watches.pop(path, None)
254                     if watch is not None:
255                         observer.unschedule(watch)
256                 self.observable_paths = paths
257                 self._sleep(self.interval)
258         finally:
259             observer.stop()
260             observer.join()
261 
262         sys.exit(3)
263 
264 
265 reloader_loops = {
266     'stat': StatReloaderLoop,
267     'watchdog': WatchdogReloaderLoop,
268 }
269 
270 try:
271     __import__('watchdog.observers')
272 except ImportError:
273     reloader_loops['auto'] = reloader_loops['stat']
274 else:
275     reloader_loops['auto'] = reloader_loops['watchdog']
276 
277 
278 def ensure_echo_on():
279     """Ensure that echo mode is enabled. Some tools such as PDB disable
280     it which causes usability issues after reload."""
281     # tcgetattr will fail if stdin isn't a tty
282     if not sys.stdin.isatty():
283         return
284     try:
285         import termios
286     except ImportError:
287         return
288     attributes = termios.tcgetattr(sys.stdin)
289     if not attributes[3] & termios.ECHO:
290         attributes[3] |= termios.ECHO
291         termios.tcsetattr(sys.stdin, termios.TCSANOW, attributes)
292 
293 
294 def run_with_reloader(main_func, extra_files=None, interval=1,
295                       reloader_type='auto'):
296     """Run the given function in an independent python interpreter."""
297     import signal
298     reloader = reloader_loops[reloader_type](extra_files, interval)
299     signal.signal(signal.SIGTERM, lambda *args: sys.exit(0))
300     try:
301         if os.environ.get('WERKZEUG_RUN_MAIN') == 'true':
302             ensure_echo_on()
303             t = threading.Thread(target=main_func, args=())
304             t.setDaemon(True)
305             t.start()
306             reloader.run()
307         else:
308             sys.exit(reloader.restart_with_reloader())
309     except KeyboardInterrupt:
310         pass
311
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/werkzeug/_reloader.py b/werkzeug/_reloader.py
--- a/werkzeug/_reloader.py
+++ b/werkzeug/_reloader.py
@@ -65,22 +65,47 @@
     """
     rv = [sys.executable]
     py_script = os.path.abspath(sys.argv[0])
+    args = sys.argv[1:]
+    # Need to look at main module to determine how it was executed.
+    __main__ = sys.modules["__main__"]
+
+    if __main__.__package__ is None:
+        # Executed a file, like "python app.py".
+        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(rv[0])[1] == ".exe"
+                and os.path.splitext(py_script)[1] == ".exe"
+            ):
+                rv.pop(0)
+
+        elif os.path.isfile(py_script) and os.access(py_script, os.X_OK):
+            # The file is marked as executable. Nix adds a wrapper that
+            # shouldn't be called with the Python executable.
+            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 misbehaves
+            args = sys.argv
+        else:
+            py_module = __main__.__package__
+            name = os.path.splitext(os.path.basename(py_script))[0]
 
-    if os.name == 'nt' and not os.path.exists(py_script) and \
-       os.path.exists(py_script + '.exe'):
-        py_script += '.exe'
-
-    windows_workaround = (
-        os.path.splitext(rv[0])[1] == '.exe'
-        and os.path.splitext(py_script)[1] == '.exe'
-    )
-    nix_workaround = os.path.isfile(py_script) and os.access(py_script, os.X_OK)
+            if name != "__main__":
+                py_module += "." + name
 
-    if windows_workaround or nix_workaround:
-        rv.pop(0)
+            rv.extend(("-m", py_module.lstrip(".")))
 
-    rv.append(py_script)
-    rv.extend(sys.argv[1:])
+    rv.extend(args)
     return rv

{"golden_diff": "diff --git a/werkzeug/_reloader.py b/werkzeug/_reloader.py\n--- a/werkzeug/_reloader.py\n+++ b/werkzeug/_reloader.py\n@@ -65,22 +65,47 @@\n     \"\"\"\n     rv = [sys.executable]\n     py_script = os.path.abspath(sys.argv[0])\n+    args = sys.argv[1:]\n+    # Need to look at main module to determine how it was executed.\n+    __main__ = sys.modules[\"__main__\"]\n+\n+    if __main__.__package__ is None:\n+        # Executed a file, like \"python app.py\".\n+        if os.name == \"nt\":\n+            # Windows entry points have \".exe\" extension and should be\n+            # called directly.\n+            if not os.path.exists(py_script) and os.path.exists(py_script + \".exe\"):\n+                py_script += \".exe\"\n+\n+            if (\n+                os.path.splitext(rv[0])[1] == \".exe\"\n+                and os.path.splitext(py_script)[1] == \".exe\"\n+            ):\n+                rv.pop(0)\n+\n+        elif os.path.isfile(py_script) and os.access(py_script, os.X_OK):\n+            # The file is marked as executable. Nix adds a wrapper that\n+            # shouldn't be called with the Python executable.\n+            rv.pop(0)\n+\n+        rv.append(py_script)\n+    else:\n+        # Executed a module, like \"python -m werkzeug.serving\".\n+        if sys.argv[0] == \"-m\":\n+            # Flask works around previous behavior by putting\n+            # \"-m flask\" in sys.argv.\n+            # TODO remove this once Flask no longer misbehaves\n+            args = sys.argv\n+        else:\n+            py_module = __main__.__package__\n+            name = os.path.splitext(os.path.basename(py_script))[0]\n \n-    if os.name == 'nt' and not os.path.exists(py_script) and \\\n-       os.path.exists(py_script + '.exe'):\n-        py_script += '.exe'\n-\n-    windows_workaround = (\n-        os.path.splitext(rv[0])[1] == '.exe'\n-        and os.path.splitext(py_script)[1] == '.exe'\n-    )\n-    nix_workaround = os.path.isfile(py_script) and os.access(py_script, os.X_OK)\n+            if name != \"__main__\":\n+                py_module += \".\" + name\n \n-    if windows_workaround or nix_workaround:\n-        rv.pop(0)\n+            rv.extend((\"-m\", py_module.lstrip(\".\")))\n \n-    rv.append(py_script)\n-    rv.extend(sys.argv[1:])\n+    rv.extend(args)\n     return rv\n", "issue": "import collision between http.py and Python 3's http modules\nHere is a (granted, obscure) way to reproduce this bug:\n1. `cd` into the `werkzeug` directory (i.e. where `serving.py`, `http.py`, etc. are located).\n2. start a Python interpreter\n3. type `import test`. This works for Python 2.x, but in Python 3.x this is what happens:\n   \n   ```\n   (venv34) werkzeug $ python\n   Python 3.4.1 (default, Sep  6 2014, 18:06:58) \n   [GCC 4.8.2] on linux\n   Type \"help\", \"copyright\", \"credits\" or \"license\" for more information.\n   >>> import test\n   Traceback (most recent call last):\n     File \"/home/miguel/Documents/dev/flask/werkzeug/werkzeug/test.py\", line 20, in <module>\n       from urllib2 import Request as U2Request\n   ImportError: No module named 'urllib2'\n   \n   During handling of the above exception, another exception occurred:\n   \n   Traceback (most recent call last):\n     File \"/home/miguel/Documents/dev/flask/werkzeug/werkzeug/http.py\", line 26, in <module>\n       from urllib2 import parse_http_list as _parse_list_header\n   ImportError: No module named 'urllib2'\n   \n   During handling of the above exception, another exception occurred:\n   \n   Traceback (most recent call last):\n     File \"<stdin>\", line 1, in <module>\n     File \"/home/miguel/Documents/dev/flask/werkzeug/werkzeug/test.py\", line 22, in <module>\n       from urllib.request import Request as U2Request\n     File \"/opt/python3.4/lib/python3.4/urllib/request.py\", line 88, in <module>\n       import http.client\n     File \"/home/miguel/Documents/dev/flask/werkzeug/werkzeug/http.py\", line 28, in <module>\n       from urllib.request import parse_http_list as _parse_list_header\n   ImportError: cannot import name 'parse_http_list'\n   >>> \n   ```\n\nThe problem is that Python 3's reorg of `httplib` into `http.xxx` modules causes an import collision between `http.client` and werkzeug's `http.py`, and `http.py` wins because its directory is in `sys.path`.\n\nI agree that the example above is pretty obscure and unlike to ever be a problem. A more likely example is when you start an application with the syntax `python -m werkzeug.serving -r module:app`. In this situation the process starts and then spawns a sub-process for the reloader. The sub-process is going to have the directory where `werkzeug.serving` is located in the `sys.path`, so the bug reproduces there as well.\n\nWould you be open to rename `http.py`? Or do you have a better idea?\n\n", "before_files": [{"content": "import os\nimport sys\nimport time\nimport subprocess\nimport threading\nfrom itertools import chain\n\nfrom werkzeug._internal import _log\nfrom werkzeug._compat import PY2, iteritems, text_type\n\n\ndef _iter_module_files():\n    \"\"\"This iterates over all relevant Python files.  It goes through all\n    loaded files from modules, all files in folders of already loaded modules\n    as well as all files reachable through a package.\n    \"\"\"\n    # The list call is necessary on Python 3 in case the module\n    # dictionary modifies during iteration.\n    for module in list(sys.modules.values()):\n        if module is None:\n            continue\n        filename = getattr(module, '__file__', None)\n        if filename:\n            if os.path.isdir(filename) and \\\n               os.path.exists(os.path.join(filename, \"__init__.py\")):\n                filename = os.path.join(filename, \"__init__.py\")\n\n            old = None\n            while not os.path.isfile(filename):\n                old = filename\n                filename = os.path.dirname(filename)\n                if filename == old:\n                    break\n            else:\n                if filename[-4:] in ('.pyc', '.pyo'):\n                    filename = filename[:-1]\n                yield filename\n\n\ndef _find_observable_paths(extra_files=None):\n    \"\"\"Finds all paths that should be observed.\"\"\"\n    rv = set(os.path.dirname(os.path.abspath(x))\n             if os.path.isfile(x) else os.path.abspath(x)\n             for x in sys.path)\n\n    for filename in extra_files or ():\n        rv.add(os.path.dirname(os.path.abspath(filename)))\n\n    for module in list(sys.modules.values()):\n        fn = getattr(module, '__file__', None)\n        if fn is None:\n            continue\n        fn = os.path.abspath(fn)\n        rv.add(os.path.dirname(fn))\n\n    return _find_common_roots(rv)\n\n\ndef _get_args_for_reloading():\n    \"\"\"Returns the executable. This contains a workaround for windows\n    if the executable is incorrectly reported to not have the .exe\n    extension which can cause bugs on reloading.  This also contains\n    a workaround for linux where the file is executable (possibly with\n    a program other than python)\n    \"\"\"\n    rv = [sys.executable]\n    py_script = os.path.abspath(sys.argv[0])\n\n    if os.name == 'nt' and not os.path.exists(py_script) and \\\n       os.path.exists(py_script + '.exe'):\n        py_script += '.exe'\n\n    windows_workaround = (\n        os.path.splitext(rv[0])[1] == '.exe'\n        and os.path.splitext(py_script)[1] == '.exe'\n    )\n    nix_workaround = os.path.isfile(py_script) and os.access(py_script, os.X_OK)\n\n    if windows_workaround or nix_workaround:\n        rv.pop(0)\n\n    rv.append(py_script)\n    rv.extend(sys.argv[1:])\n    return rv\n\n\ndef _find_common_roots(paths):\n    \"\"\"Out of some paths it finds the common roots that need monitoring.\"\"\"\n    paths = [x.split(os.path.sep) for x in paths]\n    root = {}\n    for chunks in sorted(paths, key=len, reverse=True):\n        node = root\n        for chunk in chunks:\n            node = node.setdefault(chunk, {})\n        node.clear()\n\n    rv = set()\n\n    def _walk(node, path):\n        for prefix, child in iteritems(node):\n            _walk(child, path + (prefix,))\n        if not node:\n            rv.add('/'.join(path))\n    _walk(root, ())\n    return rv\n\n\nclass ReloaderLoop(object):\n    name = None\n\n    # monkeypatched by testsuite. wrapping with `staticmethod` is required in\n    # case time.sleep has been replaced by a non-c function (e.g. by\n    # `eventlet.monkey_patch`) before we get here\n    _sleep = staticmethod(time.sleep)\n\n    def __init__(self, extra_files=None, interval=1):\n        self.extra_files = set(os.path.abspath(x)\n                               for x in extra_files or ())\n        self.interval = interval\n\n    def run(self):\n        pass\n\n    def restart_with_reloader(self):\n        \"\"\"Spawn a new Python interpreter with the same arguments as this one,\n        but running the reloader thread.\n        \"\"\"\n        while 1:\n            _log('info', ' * Restarting with %s' % self.name)\n            args = _get_args_for_reloading()\n\n            # a weird bug on windows. sometimes unicode strings end up in the\n            # environment and subprocess.call does not like this, encode them\n            # to latin1 and continue.\n            if os.name == 'nt' and PY2:\n                new_environ = {}\n                for key, value in iteritems(os.environ):\n                    if isinstance(key, text_type):\n                        key = key.encode('iso-8859-1')\n                    if isinstance(value, text_type):\n                        value = value.encode('iso-8859-1')\n                    new_environ[key] = value\n            else:\n                new_environ = os.environ.copy()\n\n            new_environ['WERKZEUG_RUN_MAIN'] = 'true'\n            exit_code = subprocess.call(args, env=new_environ,\n                                        close_fds=False)\n            if exit_code != 3:\n                return exit_code\n\n    def trigger_reload(self, filename):\n        self.log_reload(filename)\n        sys.exit(3)\n\n    def log_reload(self, filename):\n        filename = os.path.abspath(filename)\n        _log('info', ' * Detected change in %r, reloading' % filename)\n\n\nclass StatReloaderLoop(ReloaderLoop):\n    name = 'stat'\n\n    def run(self):\n        mtimes = {}\n        while 1:\n            for filename in chain(_iter_module_files(),\n                                  self.extra_files):\n                try:\n                    mtime = os.stat(filename).st_mtime\n                except OSError:\n                    continue\n\n                old_time = mtimes.get(filename)\n                if old_time is None:\n                    mtimes[filename] = mtime\n                    continue\n                elif mtime > old_time:\n                    self.trigger_reload(filename)\n            self._sleep(self.interval)\n\n\nclass WatchdogReloaderLoop(ReloaderLoop):\n\n    def __init__(self, *args, **kwargs):\n        ReloaderLoop.__init__(self, *args, **kwargs)\n        from watchdog.observers import Observer\n        from watchdog.events import FileSystemEventHandler\n        self.observable_paths = set()\n\n        def _check_modification(filename):\n            if filename in self.extra_files:\n                self.trigger_reload(filename)\n            dirname = os.path.dirname(filename)\n            if dirname.startswith(tuple(self.observable_paths)):\n                if filename.endswith(('.pyc', '.pyo', '.py')):\n                    self.trigger_reload(filename)\n\n        class _CustomHandler(FileSystemEventHandler):\n\n            def on_created(self, event):\n                _check_modification(event.src_path)\n\n            def on_modified(self, event):\n                _check_modification(event.src_path)\n\n            def on_moved(self, event):\n                _check_modification(event.src_path)\n                _check_modification(event.dest_path)\n\n            def on_deleted(self, event):\n                _check_modification(event.src_path)\n\n        reloader_name = Observer.__name__.lower()\n        if reloader_name.endswith('observer'):\n            reloader_name = reloader_name[:-8]\n        reloader_name += ' reloader'\n\n        self.name = reloader_name\n\n        self.observer_class = Observer\n        self.event_handler = _CustomHandler()\n        self.should_reload = False\n\n    def trigger_reload(self, filename):\n        # This is called inside an event handler, which means throwing\n        # SystemExit has no effect.\n        # https://github.com/gorakhargosh/watchdog/issues/294\n        self.should_reload = True\n        self.log_reload(filename)\n\n    def run(self):\n        watches = {}\n        observer = self.observer_class()\n        observer.start()\n\n        try:\n            while not self.should_reload:\n                to_delete = set(watches)\n                paths = _find_observable_paths(self.extra_files)\n                for path in paths:\n                    if path not in watches:\n                        try:\n                            watches[path] = observer.schedule(\n                                self.event_handler, path, recursive=True)\n                        except OSError:\n                            # Clear this path from list of watches We don't want\n                            # the same error message showing again in the next\n                            # iteration.\n                            watches[path] = None\n                    to_delete.discard(path)\n                for path in to_delete:\n                    watch = watches.pop(path, None)\n                    if watch is not None:\n                        observer.unschedule(watch)\n                self.observable_paths = paths\n                self._sleep(self.interval)\n        finally:\n            observer.stop()\n            observer.join()\n\n        sys.exit(3)\n\n\nreloader_loops = {\n    'stat': StatReloaderLoop,\n    'watchdog': WatchdogReloaderLoop,\n}\n\ntry:\n    __import__('watchdog.observers')\nexcept ImportError:\n    reloader_loops['auto'] = reloader_loops['stat']\nelse:\n    reloader_loops['auto'] = reloader_loops['watchdog']\n\n\ndef ensure_echo_on():\n    \"\"\"Ensure that echo mode is enabled. Some tools such as PDB disable\n    it which causes usability issues after reload.\"\"\"\n    # tcgetattr will fail if stdin isn't a tty\n    if not sys.stdin.isatty():\n        return\n    try:\n        import termios\n    except ImportError:\n        return\n    attributes = termios.tcgetattr(sys.stdin)\n    if not attributes[3] & termios.ECHO:\n        attributes[3] |= termios.ECHO\n        termios.tcsetattr(sys.stdin, termios.TCSANOW, attributes)\n\n\ndef run_with_reloader(main_func, extra_files=None, interval=1,\n                      reloader_type='auto'):\n    \"\"\"Run the given function in an independent python interpreter.\"\"\"\n    import signal\n    reloader = reloader_loops[reloader_type](extra_files, interval)\n    signal.signal(signal.SIGTERM, lambda *args: sys.exit(0))\n    try:\n        if os.environ.get('WERKZEUG_RUN_MAIN') == 'true':\n            ensure_echo_on()\n            t = threading.Thread(target=main_func, args=())\n            t.setDaemon(True)\n            t.start()\n            reloader.run()\n        else:\n            sys.exit(reloader.restart_with_reloader())\n    except KeyboardInterrupt:\n        pass\n", "path": "werkzeug/_reloader.py"}], "after_files": [{"content": "import os\nimport sys\nimport time\nimport subprocess\nimport threading\nfrom itertools import chain\n\nfrom werkzeug._internal import _log\nfrom werkzeug._compat import PY2, iteritems, text_type\n\n\ndef _iter_module_files():\n    \"\"\"This iterates over all relevant Python files.  It goes through all\n    loaded files from modules, all files in folders of already loaded modules\n    as well as all files reachable through a package.\n    \"\"\"\n    # The list call is necessary on Python 3 in case the module\n    # dictionary modifies during iteration.\n    for module in list(sys.modules.values()):\n        if module is None:\n            continue\n        filename = getattr(module, '__file__', None)\n        if filename:\n            if os.path.isdir(filename) and \\\n               os.path.exists(os.path.join(filename, \"__init__.py\")):\n                filename = os.path.join(filename, \"__init__.py\")\n\n            old = None\n            while not os.path.isfile(filename):\n                old = filename\n                filename = os.path.dirname(filename)\n                if filename == old:\n                    break\n            else:\n                if filename[-4:] in ('.pyc', '.pyo'):\n                    filename = filename[:-1]\n                yield filename\n\n\ndef _find_observable_paths(extra_files=None):\n    \"\"\"Finds all paths that should be observed.\"\"\"\n    rv = set(os.path.dirname(os.path.abspath(x))\n             if os.path.isfile(x) else os.path.abspath(x)\n             for x in sys.path)\n\n    for filename in extra_files or ():\n        rv.add(os.path.dirname(os.path.abspath(filename)))\n\n    for module in list(sys.modules.values()):\n        fn = getattr(module, '__file__', None)\n        if fn is None:\n            continue\n        fn = os.path.abspath(fn)\n        rv.add(os.path.dirname(fn))\n\n    return _find_common_roots(rv)\n\n\ndef _get_args_for_reloading():\n    \"\"\"Returns the executable. This contains a workaround for windows\n    if the executable is incorrectly reported to not have the .exe\n    extension which can cause bugs on reloading.  This also contains\n    a workaround for linux where the file is executable (possibly with\n    a program other than python)\n    \"\"\"\n    rv = [sys.executable]\n    py_script = os.path.abspath(sys.argv[0])\n    args = sys.argv[1:]\n    # Need to look at main module to determine how it was executed.\n    __main__ = sys.modules[\"__main__\"]\n\n    if __main__.__package__ is None:\n        # Executed a file, like \"python app.py\".\n        if os.name == \"nt\":\n            # Windows entry points have \".exe\" extension and should be\n            # called directly.\n            if not os.path.exists(py_script) and os.path.exists(py_script + \".exe\"):\n                py_script += \".exe\"\n\n            if (\n                os.path.splitext(rv[0])[1] == \".exe\"\n                and os.path.splitext(py_script)[1] == \".exe\"\n            ):\n                rv.pop(0)\n\n        elif os.path.isfile(py_script) and os.access(py_script, os.X_OK):\n            # The file is marked as executable. Nix adds a wrapper that\n            # shouldn't be called with the Python executable.\n            rv.pop(0)\n\n        rv.append(py_script)\n    else:\n        # Executed a module, like \"python -m werkzeug.serving\".\n        if sys.argv[0] == \"-m\":\n            # Flask works around previous behavior by putting\n            # \"-m flask\" in sys.argv.\n            # TODO remove this once Flask no longer misbehaves\n            args = sys.argv\n        else:\n            py_module = __main__.__package__\n            name = os.path.splitext(os.path.basename(py_script))[0]\n\n            if name != \"__main__\":\n                py_module += \".\" + name\n\n            rv.extend((\"-m\", py_module.lstrip(\".\")))\n\n    rv.extend(args)\n    return rv\n\n\ndef _find_common_roots(paths):\n    \"\"\"Out of some paths it finds the common roots that need monitoring.\"\"\"\n    paths = [x.split(os.path.sep) for x in paths]\n    root = {}\n    for chunks in sorted(paths, key=len, reverse=True):\n        node = root\n        for chunk in chunks:\n            node = node.setdefault(chunk, {})\n        node.clear()\n\n    rv = set()\n\n    def _walk(node, path):\n        for prefix, child in iteritems(node):\n            _walk(child, path + (prefix,))\n        if not node:\n            rv.add('/'.join(path))\n    _walk(root, ())\n    return rv\n\n\nclass ReloaderLoop(object):\n    name = None\n\n    # monkeypatched by testsuite. wrapping with `staticmethod` is required in\n    # case time.sleep has been replaced by a non-c function (e.g. by\n    # `eventlet.monkey_patch`) before we get here\n    _sleep = staticmethod(time.sleep)\n\n    def __init__(self, extra_files=None, interval=1):\n        self.extra_files = set(os.path.abspath(x)\n                               for x in extra_files or ())\n        self.interval = interval\n\n    def run(self):\n        pass\n\n    def restart_with_reloader(self):\n        \"\"\"Spawn a new Python interpreter with the same arguments as this one,\n        but running the reloader thread.\n        \"\"\"\n        while 1:\n            _log('info', ' * Restarting with %s' % self.name)\n            args = _get_args_for_reloading()\n\n            # a weird bug on windows. sometimes unicode strings end up in the\n            # environment and subprocess.call does not like this, encode them\n            # to latin1 and continue.\n            if os.name == 'nt' and PY2:\n                new_environ = {}\n                for key, value in iteritems(os.environ):\n                    if isinstance(key, text_type):\n                        key = key.encode('iso-8859-1')\n                    if isinstance(value, text_type):\n                        value = value.encode('iso-8859-1')\n                    new_environ[key] = value\n            else:\n                new_environ = os.environ.copy()\n\n            new_environ['WERKZEUG_RUN_MAIN'] = 'true'\n            exit_code = subprocess.call(args, env=new_environ,\n                                        close_fds=False)\n            if exit_code != 3:\n                return exit_code\n\n    def trigger_reload(self, filename):\n        self.log_reload(filename)\n        sys.exit(3)\n\n    def log_reload(self, filename):\n        filename = os.path.abspath(filename)\n        _log('info', ' * Detected change in %r, reloading' % filename)\n\n\nclass StatReloaderLoop(ReloaderLoop):\n    name = 'stat'\n\n    def run(self):\n        mtimes = {}\n        while 1:\n            for filename in chain(_iter_module_files(),\n                                  self.extra_files):\n                try:\n                    mtime = os.stat(filename).st_mtime\n                except OSError:\n                    continue\n\n                old_time = mtimes.get(filename)\n                if old_time is None:\n                    mtimes[filename] = mtime\n                    continue\n                elif mtime > old_time:\n                    self.trigger_reload(filename)\n            self._sleep(self.interval)\n\n\nclass WatchdogReloaderLoop(ReloaderLoop):\n\n    def __init__(self, *args, **kwargs):\n        ReloaderLoop.__init__(self, *args, **kwargs)\n        from watchdog.observers import Observer\n        from watchdog.events import FileSystemEventHandler\n        self.observable_paths = set()\n\n        def _check_modification(filename):\n            if filename in self.extra_files:\n                self.trigger_reload(filename)\n            dirname = os.path.dirname(filename)\n            if dirname.startswith(tuple(self.observable_paths)):\n                if filename.endswith(('.pyc', '.pyo', '.py')):\n                    self.trigger_reload(filename)\n\n        class _CustomHandler(FileSystemEventHandler):\n\n            def on_created(self, event):\n                _check_modification(event.src_path)\n\n            def on_modified(self, event):\n                _check_modification(event.src_path)\n\n            def on_moved(self, event):\n                _check_modification(event.src_path)\n                _check_modification(event.dest_path)\n\n            def on_deleted(self, event):\n                _check_modification(event.src_path)\n\n        reloader_name = Observer.__name__.lower()\n        if reloader_name.endswith('observer'):\n            reloader_name = reloader_name[:-8]\n        reloader_name += ' reloader'\n\n        self.name = reloader_name\n\n        self.observer_class = Observer\n        self.event_handler = _CustomHandler()\n        self.should_reload = False\n\n    def trigger_reload(self, filename):\n        # This is called inside an event handler, which means throwing\n        # SystemExit has no effect.\n        # https://github.com/gorakhargosh/watchdog/issues/294\n        self.should_reload = True\n        self.log_reload(filename)\n\n    def run(self):\n        watches = {}\n        observer = self.observer_class()\n        observer.start()\n\n        try:\n            while not self.should_reload:\n                to_delete = set(watches)\n                paths = _find_observable_paths(self.extra_files)\n                for path in paths:\n                    if path not in watches:\n                        try:\n                            watches[path] = observer.schedule(\n                                self.event_handler, path, recursive=True)\n                        except OSError:\n                            # Clear this path from list of watches We don't want\n                            # the same error message showing again in the next\n                            # iteration.\n                            watches[path] = None\n                    to_delete.discard(path)\n                for path in to_delete:\n                    watch = watches.pop(path, None)\n                    if watch is not None:\n                        observer.unschedule(watch)\n                self.observable_paths = paths\n                self._sleep(self.interval)\n        finally:\n            observer.stop()\n            observer.join()\n\n        sys.exit(3)\n\n\nreloader_loops = {\n    'stat': StatReloaderLoop,\n    'watchdog': WatchdogReloaderLoop,\n}\n\ntry:\n    __import__('watchdog.observers')\nexcept ImportError:\n    reloader_loops['auto'] = reloader_loops['stat']\nelse:\n    reloader_loops['auto'] = reloader_loops['watchdog']\n\n\ndef ensure_echo_on():\n    \"\"\"Ensure that echo mode is enabled. Some tools such as PDB disable\n    it which causes usability issues after reload.\"\"\"\n    # tcgetattr will fail if stdin isn't a tty\n    if not sys.stdin.isatty():\n        return\n    try:\n        import termios\n    except ImportError:\n        return\n    attributes = termios.tcgetattr(sys.stdin)\n    if not attributes[3] & termios.ECHO:\n        attributes[3] |= termios.ECHO\n        termios.tcsetattr(sys.stdin, termios.TCSANOW, attributes)\n\n\ndef run_with_reloader(main_func, extra_files=None, interval=1,\n                      reloader_type='auto'):\n    \"\"\"Run the given function in an independent python interpreter.\"\"\"\n    import signal\n    reloader = reloader_loops[reloader_type](extra_files, interval)\n    signal.signal(signal.SIGTERM, lambda *args: sys.exit(0))\n    try:\n        if os.environ.get('WERKZEUG_RUN_MAIN') == 'true':\n            ensure_echo_on()\n            t = threading.Thread(target=main_func, args=())\n            t.setDaemon(True)\n            t.start()\n            reloader.run()\n        else:\n            sys.exit(reloader.restart_with_reloader())\n    except KeyboardInterrupt:\n        pass\n", "path": "werkzeug/_reloader.py"}]}