Skip to content
Back to top
View this page

# asyncinotify

‘A simple optionally-async python inotify library, focused on simplicity of use and operation, and leveraging modern Python features

class asyncinotify.Event(watch: Watch | ReferenceType | None, mask: Mask, cookie: int, name: Path | None)

  Event output class.

  The `Mask` values may be tested directly against this class.

  property cookie: int

    The cookie associated with this event.

    According to the inotify man page, cookie is a unique integer that connects related events. Currently, this is used only for rename events, and allows the resulting pair of `Mask.MOVED_FROM` and `Mask.MOVED_TO` events to be connected by the application. For all other event types, cookie is set to 0.

    Returns:

      the cookie for this event

  property mask: Mask

    The mask associated with this event

    Returns:

      the mask for this event

  property name: Path | None

    The name associated with the event. May be None, indicating the watch directory itself.

    Returns:

      the name of the event, or None if the event is for the watch itself

  property path: Path | None

    The full path to this event, constructed from the `Watch` path and the `name()`.

    If the `Watch` no longer exists, this returns None. If the `name()` does not exist, just returns the watch path. This value is absolute if the path used to construct the `Watch` (the path used with `Inotify.add_watch()`) is absolute, otherwise it is relative. This means if you have changed directory between constructing a watch with a relative path and receiving this event, you will have to have another way of identifying the file correctly.

    Returns:

      the full path for the event, or None if it can not be constructed.

  property watch: Watch | None

    The actual Watch instance associated with this event.

    This is stored internally as a weak reference. If the event is taken out of context and outlives its generating `Inotify`, this may return None.

    If `mask()` contains IGNORED or the watch was a ONESHOT, this is not a weak reference, but the actual watch instance. If the watch was ONESHOT, the corresponding IGNORED will not have a watch instance, only the ONESHOT event itself. This may be inconvenient, but the inotify man page doesn’t give strong enough guarantees to risk memory leak with ONESHOT events by leaving the ownership change exclusively to IGNORED events.

    Returns:

      the watch instance that generated this

class asyncinotify.InitFlags(*values)

  Init flags for use with the `Inotify` constructor.

  You shouldn’t have a reason to use this, as `CLOEXEC` will be desired because there’s no reason for exec’d children to inherit inotify handles here, and `NONBLOCK` shouldn’t even make a difference due to the handle always being watched with select, unless you are using synchronous mode.

  CLOEXEC = 524288

    Set the close-on-exec (FD_CLOEXEC) flag on the new file descriptor if it exists. See the description of the O_CLOEXEC flag in open(2) for reasons why this may be useful.

  NONBLOCK = 524288

    Set the O_NONBLOCK file status flag on the open file description if it exists (see open(2)) referred to by the new file descriptor. Using this flag saves extra calls to fcntl(2) to achieve the same result.

class asyncinotify.Inotify(flags: ~asyncinotify.InitFlags = <InitFlags.CLOEXEC: 524288>, cache_size: int = 10, sync_timeout: float | None = None)

  Core Inotify class.

  Fetches events in bulk, if possible, and stores them internally.

  Use `get()` to get a single event. This class operates as an async generator, and may be asynchronously iterated, and will return events forever.

  Parameters:

    - cache_size (int) – The max number of full-size events to cache. The actual number may be higher, because most events will not be full-sized.

    - sync_timeout – If this is not None, then sync_get will wait on an selector call for that long, and return None on a timeout. Normal iteration will also exit on a timeout.

  add_watch(path: PathLike | bytes | str, mask: Mask) → Watch

    Add a watch dir.

    Parameters:

      - path (pathlib.Path) – a string, bytes, or PathLike object

      - mask (Mask) – a Mask determining how the watch behaves

    Returns:

      The relevant Watch instance

  property cache_size: int

    The maximum number of full-sized events (events with a NAME_MAX-length name) to store.

    More events may be stored, because very few events should use a NAME_MAX length name.

  close() → None

    Close the file descriptor for this inotify.

    Once this is done, do not do anything more with this inotify instance. Associated `Watch` and `Event` instances are still valid, but no more may be created, and if this `Inotify` goes out of scope and is cleaned up, the `Event` may lose its `Watch` if you don’t have a reference to it.

    This is automatically called when this class is used as a context manager.

  property fd: int

    Get the raw file descriptor.

  async get() → Event

    Get a single next event.

    This is the core method of event retrieval. Asynchronously iterating this class simply calls this method forever.

    May actually pull multiple events from the inotify handle, and store extras internally. Will always only return one.

    Building some events may cause changes in the associated `Inotify` or `Watch` instances. For instance, `Mask.IGNORE` will automatically remove its `Watch` instance from this `Inotify` object. A `Mask.ONESHOT` Watch will remove itself on the first event.

    Caution

    A watched path being moved will cause the relevant `Watch.path()` to be incorrect. This library will not automatically update it for you, because `Mask.MOVE_SELF` does not tell you the new name. You would have to watch the parent directory and change the `Watch.path()` value yourself if you want that functionality.

    If you don’t do this and the watch path is moved, the `Event` will have a correct name but incorrect path.

    Returns:

      a single `Event`

  rm_watch(watch: Watch) → None

    Remove a watch from this inotify instance.

    This will generate an `Mask.IGNORED` event that contains the `Watch` instance.

    Parameters:

      watch (Watch) – the `Watch` to remove

  sync_get() → Event | None

    Get a single next event synchronously, or throw a blocking error if you’ve opened this in nonblocking mode.

    All concerns that apply to `get()` also apply to this method.

    Returns:

      a single `Event`, or None if sync_timeout is not None and the poll timed out.

  property sync_timeout: float | None

    The timeout for `sync_get()` and synchronous iteration.

    Set this to None to disable and -1 to wait forever. These options can be different depending on the blocking flags selected.

class asyncinotify.Mask(*values)

  Bit-mask for adding a watch and for analyzing watch events.

  Because this is an IntFlag, all IntFlag operations work on it, such as using the bitwise or operator to combine, or using the in operator to check contents.

  ACCESS = 1

    File was accessed (e.g., read(2), execve(2)).

  ALL = 4095

    Monitor all common types of events. This does not include modifier flags like ONESHOT, MASK_CREATE, EXEC_UNLINK, etc.

  ATTRIB = 4

    Metadata changed—for example, permissions (e.g., chmod(2)), timestamps (e.g., utimensat(2)), extended attributes (setxattr(2)), link count (since Linux 2.6.25; e.g., for the target of link(2) and for unlink(2)), and user/group ID (e.g., chown(2)).

  CLOSE = 24

    `CLOSE_WRITE` | `CLOSE_NOWRITE`

  CLOSE_NOWRITE = 16

    File or directory not opened for writing was closed.

  CLOSE_WRITE = 8

    File opened for writing was closed.

  CREATE = 256

    File/directory created in watched directory (e.g., open(2) O_CREAT, mkdir(2), link(2), symlink(2), bind(2) on a UNIX domain socket).

  DELETE = 512

    File/directory deleted from watched directory.

  DELETE_SELF = 1024

    Watched file/directory was itself deleted. (This event also occurs if an object is moved to another filesystem, since mv(1) in effect copies the file to the other filesystem and then deletes it from the original filesystem.) In addition, an `Mask.IGNORED` event will subsequently be generated for the watch descriptor.

  DONT_FOLLOW = 33554432

    Don’t dereference pathname if it is a symbolic link.

  EXCL_UNLINK = 67108864

    By default, when watching events on the children of a directory, events are generated for children even after they have been unlinked from the directory. This can result in large numbers of uninteresting events for some applications (e.g., if watching /tmp, in which many applications create temporary files whose names are immediately unlinked). Specifying `Mask.EXCL_UNLINK` changes the default behavior, so that events are not generated for children after they have been unlinked from the watched directory.

  IGNORED = 32768

    Watch was removed explicitly (inotify_rm_watch(2)) or automatically (file was deleted, or filesystem was unmounted).

  ISDIR = 1073741824

    Subject of this event is a directory.

  MASK_ADD = 536870912

    If a watch instance already exists for the filesystem object corresponding to pathname, add (OR) the events in mask to the watch mask (instead of replacing the mask); the error EINVAL results if `Mask.MASK_CREATE` is also specified.

  MASK_CREATE = 268435456

    (since Linux 4.18) Watch pathname only if it does not already have a watch associated with it; the error EEXIST results if pathname is already being watched. Using this flag provides an application with a way of ensuring that new watches do not modify existing ones. This is useful because multiple paths may refer to the same inode, and multiple calls to inotify_add_watch(2) without this flag may clobber existing watch masks.

  MODIFY = 2

    File was modified (e.g., write(2), truncate(2)).

  MOVE = 192

    `MOVED_FROM: | :attr:`MOVED_TO`

  MOVED_FROM = 64

    Generated for the directory containing the old filename when a file is renamed. Note the cookie member in `Event`.

  MOVED_TO = 128

    Generated for the directory containing the new filename when a file is renamed. Note the cookie member in `Event`.

  MOVE_SELF = 2048

    Watched file/directory was itself moved.

  ONESHOT = 2147483648

    Monitor the filesystem object corresponding to pathname for one event, then remove from watch list.

  ONLYDIR = 16777216

    (since Linux 2.6.15) Watch pathname only if it is a directory; the error ENOTDIR results if pathname is not a directory. Using this flag provides an application with a race-free way of ensuring that the monitored object is a directory.

  OPEN = 32

    File or directory was opened.

  Q_OVERFLOW = 16384

    Event queue overflowed (wd is -1 for this event (`Event.watch()` will be None)).

  UNMOUNT = 8192

    Filesystem containing watched object was unmounted. In addition, an `Mask.IGNORED` event will subsequently be generated for the watch descriptor.

  ZERO = 0

    No flag, to facilitate defaults

class asyncinotify.RecursiveInotify

  A Recursive superclass of Inotify.

  Adds the `add_recursive_watch()` method, but otherwise works the same.

  Automatically adds and removes subdirectories as they are added and removed.

  add_recursive_watch(path: Path, mask: Mask | None = None) → List[Watch]

    Add a watch for the given directory path, which must be a directory, and all subdirectories.

    Returns the watch for this path and all subdirectories, breadth-first (so the passed-in path is always first in the list.

  async get() → Event

    Get a single next event.

    This is the core method of event retrieval. Asynchronously iterating this class simply calls this method forever.

    May actually pull multiple events from the inotify handle, and store extras internally. Will always only return one.

    Building some events may cause changes in the associated `Inotify` or `Watch` instances. For instance, `Mask.IGNORE` will automatically remove its `Watch` instance from this `Inotify` object. A `Mask.ONESHOT` Watch will remove itself on the first event.

    Caution

    A watched path being moved will cause the relevant `Watch.path()` to be incorrect. This library will not automatically update it for you, because `Mask.MOVE_SELF` does not tell you the new name. You would have to watch the parent directory and change the `Watch.path()` value yourself if you want that functionality.

    If you don’t do this and the watch path is moved, the `Event` will have a correct name but incorrect path.

    Returns:

      a single `Event`

  sync_get() → Event | None

    Get a single next event synchronously, or throw a blocking error if you’ve opened this in nonblocking mode.

    All concerns that apply to `get()` also apply to this method.

    Returns:

      a single `Event`, or None if sync_timeout is not None and the poll timed out.

class asyncinotify.RecursiveWatcher(path, mask)

  watch a folder recursively: add a watch when a folder is created/moved in delete a watch when a folder is deleted/moved out this also works for folders moving within the watched folders because both move_from event and move_to event will be caught

class asyncinotify.Watch(inotify: Inotify, path: Path, mask: Mask, wd: int)

  Watch class.

  You usually won’t construct this directly, but rather use `Inotify.add_watch()` to create it.

  property inotify: Inotify | None

    The `Inotify` instance this Watch belongs to.

    This is internally stored as a weakref, so if the `Watch` outlives the `Inotify`, this may return None.

    Returns:

      The `Inotify` instance this Watch belongs to.

  property mask: Mask
    Returns:

      The mask that was used to construct this watch

  property path: Path

    The path that this watch is for.

  property wd: int

    The raw watch descriptor.