actualizado 3-sept

This commit is contained in:
2026-09-03 19:40:44 +02:00
parent 89992823b4
commit 5d2912f789
4338 changed files with 350157 additions and 386 deletions
+142
View File
@@ -0,0 +1,142 @@
#
# This file is part of gunicorn released under the MIT license.
# See the NOTICE for more information.
# pylint: disable=no-else-continue
import glob
import os
import os.path
import re
import sys
import time
import threading
from gunicorn import util
COMPILED_EXT_RE = re.compile(r'py[co]$')
class ReloaderBase(threading.Thread):
def __init__(self, extra_files=None, interval=1, callback=None):
super().__init__()
self.daemon = True
self._extra_files = set()
self._extra_patterns = set()
for entry in extra_files or ():
if util.is_glob_pattern(entry):
self._extra_patterns.add(entry)
else:
self._extra_files.add(entry)
self._interval = interval
self._callback = callback
def add_extra_file(self, filename):
self._extra_files.add(filename)
def get_files(self):
fnames = [
COMPILED_EXT_RE.sub('py', module.__file__)
for module in tuple(sys.modules.values())
if getattr(module, '__file__', None)
]
fnames.extend(self._extra_files)
# Expanded on every call rather than once at startup, so that files
# created after the server booted are picked up too.
for pattern in self._extra_patterns:
fnames.extend(sorted(glob.glob(pattern, recursive=True)))
return fnames
class Reloader(ReloaderBase):
def run(self):
mtimes = {}
while True:
for filename in self.get_files():
try:
mtime = os.stat(filename).st_mtime
except OSError:
continue
old_time = mtimes.get(filename)
if old_time is None:
mtimes[filename] = mtime
continue
elif mtime > old_time:
if self._callback:
self._callback(filename)
time.sleep(self._interval)
has_inotify = False
if sys.platform.startswith('linux'):
try:
from inotify.adapters import Inotify
import inotify.constants
has_inotify = True
except ImportError:
pass
if has_inotify:
class InotifyReloader(ReloaderBase):
event_mask = (inotify.constants.IN_CREATE | inotify.constants.IN_DELETE
| inotify.constants.IN_DELETE_SELF | inotify.constants.IN_MODIFY
| inotify.constants.IN_MOVE_SELF | inotify.constants.IN_MOVED_FROM
| inotify.constants.IN_MOVED_TO)
def __init__(self, extra_files=None, callback=None):
super().__init__(extra_files=extra_files, callback=callback)
self._dirs = set()
self._watcher = Inotify()
def add_extra_file(self, filename):
super().add_extra_file(filename)
dirname = os.path.dirname(filename) or '.'
if dirname in self._dirs:
return
self._watcher.add_watch(dirname, mask=self.event_mask)
self._dirs.add(dirname)
def get_dirs(self):
dirnames = [os.path.dirname(os.path.abspath(fname)) for fname in self.get_files()]
return set(dirnames)
def refresh_dirs(self):
new_dirs = self.get_dirs().difference(self._dirs)
self._dirs.update(new_dirs)
for new_dir in new_dirs:
if os.path.isdir(new_dir):
self._watcher.add_watch(new_dir, mask=self.event_mask)
def run(self):
self.refresh_dirs()
for event in self._watcher.event_gen():
if event is None:
self.refresh_dirs()
continue
filename = event[3]
self._callback(filename)
else:
class InotifyReloader:
def __init__(self, extra_files=None, callback=None):
raise ImportError('You must have the inotify module installed to '
'use the inotify reloader')
preferred_reloader = InotifyReloader if has_inotify else Reloader
reloader_engines = {
'auto': preferred_reloader,
'poll': Reloader,
'inotify': InotifyReloader,
}