def _reloader_inotify(extra_files=None, interval=None):
    # Mutated by inotify loop when changes occur.
    changed = [False]

    # Setup inotify watches
    from pyinotify import WatchManager, Notifier

    # this API changed at one point, support both
    try:
        from pyinotify import EventsCodes as ec
        ec.IN_ATTRIB
    except (ImportError, AttributeError):
        import pyinotify as ec

    wm = WatchManager()
    mask = ec.IN_DELETE_SELF | ec.IN_MOVE_SELF | ec.IN_MODIFY | ec.IN_ATTRIB

    def signal_changed(event):
        if changed[0]:
            return
        _log('info', ' * Detected change in %r, reloading' % event.path)
        changed[:] = [True]

    for fname in extra_files or ():
        wm.add_watch(fname, mask, signal_changed)

    # ... And now we wait...
    notif = Notifier(wm)
    try:
        while not changed[0]:
            # always reiterate through sys.modules, adding them
            for fname in _iter_module_files():
                wm.add_watch(fname, mask, signal_changed)
            notif.process_events()
            if notif.check_events(timeout=interval):
                notif.read_events()
            # TODO Set timeout to something small and check parent liveliness
    finally:
        notif.stop()
    sys.exit(3)


# currently we always use the stat loop reloader for the simple reason
# that the inotify one does not respond to added files properly.  Also
# it's quite buggy and the API is a mess.
dataset/ETHPy150Open Eforcers/gae-flask-todo/lib/werkzeug/serving.py/_reloader_inotify/original