prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  gunicorn crashed on start with --reload flag
  Setup: Vagrant, virtualenv, gunicorn 19.3.0:
  
  The following command produces this stack:
  
  `gunicorn -c /data/shared/api/gunicorn_config.py -b unix:/tmp/api-dev-gunicorn.sock --log-level INFO --reload  wsgi:app`
  
  ```
  Exception in thread Thread-1:
  Traceback (most recent call last):
    File "/home/vagrant/.pyenv/versions/2.7.6/lib/python2.7/threading.py", line 810, in __bootstrap_inner
      self.run()
    File "/data/virtualenv/default/lib/python2.7/site-packages/gunicorn/reloader.py", line 41, in run
      for filename in self.get_files():
    File "/data/virtualenv/default/lib/python2.7/site-packages/gunicorn/reloader.py", line 30, in get_files
      if hasattr(module, '__file__')
    File "/data/virtualenv/default/lib/python2.7/re.py", line 151, in sub
      return _compile(pattern, flags).sub(repl, string, count)
  TypeError: expected string or buffer
  ```
  
  If I remove --reload it boots up fine.
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `gunicorn/reloader.py`
  Content:
  ```
  1 # -*- coding: utf-8 -
  2 #
  3 # This file is part of gunicorn released under the MIT license.
  4 # See the NOTICE for more information.
  5 
  6 import os
  7 import os.path
  8 import re
  9 import sys
  10 import time
  11 import threading
  12 
  13 
  14 class Reloader(threading.Thread):
  15     def __init__(self, extra_files=None, interval=1, callback=None):
  16         super(Reloader, self).__init__()
  17         self.setDaemon(True)
  18         self._extra_files = set(extra_files or ())
  19         self._extra_files_lock = threading.RLock()
  20         self._interval = interval
  21         self._callback = callback
  22 
  23     def add_extra_file(self, filename):
  24         with self._extra_files_lock:
  25             self._extra_files.add(filename)
  26 
  27     def get_files(self):
  28         fnames = [
  29             re.sub('py[co]$', 'py', module.__file__)
  30             for module in list(sys.modules.values())
  31             if hasattr(module, '__file__')
  32         ]
  33 
  34         with self._extra_files_lock:
  35             fnames.extend(self._extra_files)
  36 
  37         return fnames
  38 
  39     def run(self):
  40         mtimes = {}
  41         while True:
  42             for filename in self.get_files():
  43                 try:
  44                     mtime = os.stat(filename).st_mtime
  45                 except OSError:
  46                     continue
  47                 old_time = mtimes.get(filename)
  48                 if old_time is None:
  49                     mtimes[filename] = mtime
  50                     continue
  51                 elif mtime > old_time:
  52                     if self._callback:
  53                         self._callback(filename)
  54             time.sleep(self._interval)
  55 
  56 has_inotify = False
  57 if sys.platform.startswith('linux'):
  58     try:
  59         from inotify.adapters import Inotify
  60         import inotify.constants
  61         has_inotify = True
  62     except ImportError:
  63         pass
  64 
  65 
  66 if has_inotify:
  67 
  68     class InotifyReloader(threading.Thread):
  69         event_mask = (inotify.constants.IN_CREATE | inotify.constants.IN_DELETE
  70                       | inotify.constants.IN_DELETE_SELF | inotify.constants.IN_MODIFY
  71                       | inotify.constants.IN_MOVE_SELF | inotify.constants.IN_MOVED_FROM
  72                       | inotify.constants.IN_MOVED_TO)
  73 
  74         def __init__(self, extra_files=None, callback=None):
  75             super(InotifyReloader, self).__init__()
  76             self.setDaemon(True)
  77             self._callback = callback
  78             self._dirs = set()
  79             self._watcher = Inotify()
  80 
  81             for extra_file in extra_files:
  82                 self.add_extra_file(extra_file)
  83 
  84         def add_extra_file(self, filename):
  85             dirname = os.path.dirname(filename)
  86 
  87             if dirname in self._dirs:
  88                 return
  89 
  90             self._watcher.add_watch(dirname, mask=self.event_mask)
  91             self._dirs.add(dirname)
  92 
  93         def get_dirs(self):
  94             fnames = [
  95                 os.path.dirname(re.sub('py[co]$', 'py', module.__file__))
  96                 for module in list(sys.modules.values())
  97                 if hasattr(module, '__file__')
  98             ]
  99 
  100             return set(fnames)
  101 
  102         def run(self):
  103             self._dirs = self.get_dirs()
  104 
  105             for dirname in self._dirs:
  106                 self._watcher.add_watch(dirname, mask=self.event_mask)
  107 
  108             for event in self._watcher.event_gen():
  109                 if event is None:
  110                     continue
  111 
  112                 filename = event[3]
  113 
  114                 self._callback(filename)
  115 
  116 else:
  117 
  118     class InotifyReloader(object):
  119         def __init__(self, callback=None):
  120             raise ImportError('You must have the inotify module installed to '
  121                               'use the inotify reloader')
  122 
  123 
  124 preferred_reloader = InotifyReloader if has_inotify else Reloader
  125 
  126 reloader_engines = {
  127     'auto': preferred_reloader,
  128     'poll': Reloader,
  129     'inotify': InotifyReloader,
  130 }
  131
  ```
  --- 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()
  
  ```
  
golden_diff: diff --git a/gunicorn/reloader.py b/gunicorn/reloader.py
  --- a/gunicorn/reloader.py
  +++ b/gunicorn/reloader.py
  @@ -28,7 +28,7 @@
           fnames = [
               re.sub('py[co]$', 'py', module.__file__)
               for module in list(sys.modules.values())
  -            if hasattr(module, '__file__')
  +            if getattr(module, '__file__', None)
           ]
   
           with self._extra_files_lock:
  
verification_info: {"golden_diff": "diff --git a/gunicorn/reloader.py b/gunicorn/reloader.py\n--- a/gunicorn/reloader.py\n+++ b/gunicorn/reloader.py\n@@ -28,7 +28,7 @@\n         fnames = [\n             re.sub('py[co]$', 'py', module.__file__)\n             for module in list(sys.modules.values())\n-            if hasattr(module, '__file__')\n+            if getattr(module, '__file__', None)\n         ]\n \n         with self._extra_files_lock:\n", "issue": "gunicorn crashed on start with --reload flag\nSetup: Vagrant, virtualenv, gunicorn 19.3.0:\n\nThe following command produces this stack:\n\n`gunicorn -c /data/shared/api/gunicorn_config.py -b unix:/tmp/api-dev-gunicorn.sock --log-level INFO --reload  wsgi:app`\n\n```\nException in thread Thread-1:\nTraceback (most recent call last):\n  File \"/home/vagrant/.pyenv/versions/2.7.6/lib/python2.7/threading.py\", line 810, in __bootstrap_inner\n    self.run()\n  File \"/data/virtualenv/default/lib/python2.7/site-packages/gunicorn/reloader.py\", line 41, in run\n    for filename in self.get_files():\n  File \"/data/virtualenv/default/lib/python2.7/site-packages/gunicorn/reloader.py\", line 30, in get_files\n    if hasattr(module, '__file__')\n  File \"/data/virtualenv/default/lib/python2.7/re.py\", line 151, in sub\n    return _compile(pattern, flags).sub(repl, string, count)\nTypeError: expected string or buffer\n```\n\nIf I remove --reload it boots up fine.\n\n", "before_files": [{"content": "# -*- coding: utf-8 -\n#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\nimport os\nimport os.path\nimport re\nimport sys\nimport time\nimport threading\n\n\nclass Reloader(threading.Thread):\n    def __init__(self, extra_files=None, interval=1, callback=None):\n        super(Reloader, self).__init__()\n        self.setDaemon(True)\n        self._extra_files = set(extra_files or ())\n        self._extra_files_lock = threading.RLock()\n        self._interval = interval\n        self._callback = callback\n\n    def add_extra_file(self, filename):\n        with self._extra_files_lock:\n            self._extra_files.add(filename)\n\n    def get_files(self):\n        fnames = [\n            re.sub('py[co]$', 'py', module.__file__)\n            for module in list(sys.modules.values())\n            if hasattr(module, '__file__')\n        ]\n\n        with self._extra_files_lock:\n            fnames.extend(self._extra_files)\n\n        return fnames\n\n    def run(self):\n        mtimes = {}\n        while True:\n            for filename in self.get_files():\n                try:\n                    mtime = os.stat(filename).st_mtime\n                except OSError:\n                    continue\n                old_time = mtimes.get(filename)\n                if old_time is None:\n                    mtimes[filename] = mtime\n                    continue\n                elif mtime > old_time:\n                    if self._callback:\n                        self._callback(filename)\n            time.sleep(self._interval)\n\nhas_inotify = False\nif sys.platform.startswith('linux'):\n    try:\n        from inotify.adapters import Inotify\n        import inotify.constants\n        has_inotify = True\n    except ImportError:\n        pass\n\n\nif has_inotify:\n\n    class InotifyReloader(threading.Thread):\n        event_mask = (inotify.constants.IN_CREATE | inotify.constants.IN_DELETE\n                      | inotify.constants.IN_DELETE_SELF | inotify.constants.IN_MODIFY\n                      | inotify.constants.IN_MOVE_SELF | inotify.constants.IN_MOVED_FROM\n                      | inotify.constants.IN_MOVED_TO)\n\n        def __init__(self, extra_files=None, callback=None):\n            super(InotifyReloader, self).__init__()\n            self.setDaemon(True)\n            self._callback = callback\n            self._dirs = set()\n            self._watcher = Inotify()\n\n            for extra_file in extra_files:\n                self.add_extra_file(extra_file)\n\n        def add_extra_file(self, filename):\n            dirname = os.path.dirname(filename)\n\n            if dirname in self._dirs:\n                return\n\n            self._watcher.add_watch(dirname, mask=self.event_mask)\n            self._dirs.add(dirname)\n\n        def get_dirs(self):\n            fnames = [\n                os.path.dirname(re.sub('py[co]$', 'py', module.__file__))\n                for module in list(sys.modules.values())\n                if hasattr(module, '__file__')\n            ]\n\n            return set(fnames)\n\n        def run(self):\n            self._dirs = self.get_dirs()\n\n            for dirname in self._dirs:\n                self._watcher.add_watch(dirname, mask=self.event_mask)\n\n            for event in self._watcher.event_gen():\n                if event is None:\n                    continue\n\n                filename = event[3]\n\n                self._callback(filename)\n\nelse:\n\n    class InotifyReloader(object):\n        def __init__(self, callback=None):\n            raise ImportError('You must have the inotify module installed to '\n                              'use the inotify reloader')\n\n\npreferred_reloader = InotifyReloader if has_inotify else Reloader\n\nreloader_engines = {\n    'auto': preferred_reloader,\n    'poll': Reloader,\n    'inotify': InotifyReloader,\n}\n", "path": "gunicorn/reloader.py"}], "after_files": [{"content": "# -*- coding: utf-8 -\n#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\nimport os\nimport os.path\nimport re\nimport sys\nimport time\nimport threading\n\n\nclass Reloader(threading.Thread):\n    def __init__(self, extra_files=None, interval=1, callback=None):\n        super(Reloader, self).__init__()\n        self.setDaemon(True)\n        self._extra_files = set(extra_files or ())\n        self._extra_files_lock = threading.RLock()\n        self._interval = interval\n        self._callback = callback\n\n    def add_extra_file(self, filename):\n        with self._extra_files_lock:\n            self._extra_files.add(filename)\n\n    def get_files(self):\n        fnames = [\n            re.sub('py[co]$', 'py', module.__file__)\n            for module in list(sys.modules.values())\n            if getattr(module, '__file__', None)\n        ]\n\n        with self._extra_files_lock:\n            fnames.extend(self._extra_files)\n\n        return fnames\n\n    def run(self):\n        mtimes = {}\n        while True:\n            for filename in self.get_files():\n                try:\n                    mtime = os.stat(filename).st_mtime\n                except OSError:\n                    continue\n                old_time = mtimes.get(filename)\n                if old_time is None:\n                    mtimes[filename] = mtime\n                    continue\n                elif mtime > old_time:\n                    if self._callback:\n                        self._callback(filename)\n            time.sleep(self._interval)\n\nhas_inotify = False\nif sys.platform.startswith('linux'):\n    try:\n        from inotify.adapters import Inotify\n        import inotify.constants\n        has_inotify = True\n    except ImportError:\n        pass\n\n\nif has_inotify:\n\n    class InotifyReloader(threading.Thread):\n        event_mask = (inotify.constants.IN_CREATE | inotify.constants.IN_DELETE\n                      | inotify.constants.IN_DELETE_SELF | inotify.constants.IN_MODIFY\n                      | inotify.constants.IN_MOVE_SELF | inotify.constants.IN_MOVED_FROM\n                      | inotify.constants.IN_MOVED_TO)\n\n        def __init__(self, extra_files=None, callback=None):\n            super(InotifyReloader, self).__init__()\n            self.setDaemon(True)\n            self._callback = callback\n            self._dirs = set()\n            self._watcher = Inotify()\n\n            for extra_file in extra_files:\n                self.add_extra_file(extra_file)\n\n        def add_extra_file(self, filename):\n            dirname = os.path.dirname(filename)\n\n            if dirname in self._dirs:\n                return\n\n            self._watcher.add_watch(dirname, mask=self.event_mask)\n            self._dirs.add(dirname)\n\n        def get_dirs(self):\n            fnames = [\n                os.path.dirname(re.sub('py[co]$', 'py', module.__file__))\n                for module in list(sys.modules.values())\n                if hasattr(module, '__file__')\n            ]\n\n            return set(fnames)\n\n        def run(self):\n            self._dirs = self.get_dirs()\n\n            for dirname in self._dirs:\n                self._watcher.add_watch(dirname, mask=self.event_mask)\n\n            for event in self._watcher.event_gen():\n                if event is None:\n                    continue\n\n                filename = event[3]\n\n                self._callback(filename)\n\nelse:\n\n    class InotifyReloader(object):\n        def __init__(self, callback=None):\n            raise ImportError('You must have the inotify module installed to '\n                              'use the inotify reloader')\n\n\npreferred_reloader = InotifyReloader if has_inotify else Reloader\n\nreloader_engines = {\n    'auto': preferred_reloader,\n    'poll': Reloader,\n    'inotify': InotifyReloader,\n}\n", "path": "gunicorn/reloader.py"}]}