Python library and shell utilities to monitor filesystem events.

Overview

Watchdog

https://travis-ci.org/gorakhargosh/watchdog.svg?branch=master

Python API and shell utilities to monitor file system events.

Works on 3.6+.

If you want to use Python 2.6, you should stick with watchdog < 0.10.0.

If you want to use Python 2.7, 3.4 or 3.5, you should stick with watchdog < 1.0.0.

Example API Usage

A simple program that uses watchdog to monitor directories specified as command-line arguments and logs events generated:

import sys
import time
import logging
from watchdog.observers import Observer
from watchdog.events import LoggingEventHandler

if __name__ == "__main__":
    logging.basicConfig(level=logging.INFO,
                        format='%(asctime)s - %(message)s',
                        datefmt='%Y-%m-%d %H:%M:%S')
    path = sys.argv[1] if len(sys.argv) > 1 else '.'
    event_handler = LoggingEventHandler()
    observer = Observer()
    observer.schedule(event_handler, path, recursive=True)
    observer.start()
    try:
        while True:
            time.sleep(1)
    finally:
        observer.stop()
        observer.join()

Shell Utilities

Watchdog comes with an optional utility script called watchmedo. Please type watchmedo --help at the shell prompt to know more about this tool.

Here is how you can log the current directory recursively for events related only to *.py and *.txt files while ignoring all directory events:

watchmedo log \
    --patterns="*.py;*.txt" \
    --ignore-directories \
    --recursive \
    .

You can use the shell-command subcommand to execute shell commands in response to events:

watchmedo shell-command \
    --patterns="*.py;*.txt" \
    --recursive \
    --command='echo "${watch_src_path}"' \
    .

Please see the help information for these commands by typing:

watchmedo [command] --help

About watchmedo Tricks

watchmedo can read tricks.yaml files and execute tricks within them in response to file system events. Tricks are actually event handlers that subclass watchdog.tricks.Trick and are written by plugin authors. Trick classes are augmented with a few additional features that regular event handlers don't need.

An example tricks.yaml file:

tricks:
- watchdog.tricks.LoggerTrick:
    patterns: ["*.py", "*.js"]
- watchmedo_webtricks.GoogleClosureTrick:
    patterns: ['*.js']
    hash_names: true
    mappings_format: json                  # json|yaml|python
    mappings_module: app/javascript_mappings
    suffix: .min.js
    compilation_level: advanced            # simple|advanced
    source_directory: app/static/js/
    destination_directory: app/public/js/
    files:
      index-page:
      - app/static/js/vendor/jquery*.js
      - app/static/js/base.js
      - app/static/js/index-page.js
      about-page:
      - app/static/js/vendor/jquery*.js
      - app/static/js/base.js
      - app/static/js/about-page/**/*.js

The directory containing the tricks.yaml file will be monitored. Each trick class is initialized with its corresponding keys in the tricks.yaml file as arguments and events are fed to an instance of this class as they arrive.

Installation

Install from PyPI using pip:

$ python -m pip install -U watchdog

# or to install the watchmedo utility:
$ python -m pip install -U watchdog[watchmedo]

Install from source:

$ python -m pip install -e .

# or to install the watchmedo utility:
$ python -m pip install -e ".[watchmedo]"

Installation Caveats

The watchmedo script depends on PyYAML which links with LibYAML, which brings a performance boost to the PyYAML parser. However, installing LibYAML is optional but recommended. On Mac OS X, you can use homebrew to install LibYAML:

$ brew install libyaml

On Linux, use your favorite package manager to install LibYAML. Here's how you do it on Ubuntu:

$ sudo apt install libyaml-dev

On Windows, please install PyYAML using the binaries they provide.

Documentation

You can browse the latest release documentation online.

Contribute

Fork the repository on GitHub and send a pull request, or file an issue ticket at the issue tracker. For general help and questions use the official mailing list or ask on stackoverflow with tag python-watchdog.

Create and activate your virtual environment, then:

python -m pip install pytest pytest-cov
python -m pip install -e ".[watchmedo]"
python -m pytest tests

If you are making a substantial change, add an entry to the "Unreleased" section of the changelog.

Supported Platforms

  • Linux 2.6 (inotify)
  • Mac OS X (FSEvents, kqueue)
  • FreeBSD/BSD (kqueue)
  • Windows (ReadDirectoryChangesW with I/O completion ports; ReadDirectoryChangesW worker threads)
  • OS-independent (polling the disk for directory snapshots and comparing them periodically; slow and not recommended)

Note that when using watchdog with kqueue, you need the number of file descriptors allowed to be opened by programs running on your system to be increased to more than the number of files that you will be monitoring. The easiest way to do that is to edit your ~/.profile file and add a line similar to:

ulimit -n 1024

This is an inherent problem with kqueue because it uses file descriptors to monitor files. That plus the enormous amount of bookkeeping that watchdog needs to do in order to monitor file descriptors just makes this a painful way to monitor files and directories. In essence, kqueue is not a very scalable way to monitor a deeply nested directory of files and directories with a large number of files.

About using watchdog with editors like Vim

Vim does not modify files unless directed to do so. It creates backup files and then swaps them in to replace the files you are editing on the disk. This means that if you use Vim to edit your files, the on-modified events for those files will not be triggered by watchdog. You may need to configure Vim appropriately to disable this feature.

About using watchdog with CIFS

When you want to watch changes in CIFS, you need to explicitly tell watchdog to use PollingObserver, that is, instead of letting watchdog decide an appropriate observer like in the example above, do:

from watchdog.observers.polling import PollingObserver as Observer

Dependencies

  1. Python 3.6 or above.
  2. XCode (only on Mac OS X)
  3. PyYAML (only for watchmedo script)
  4. argh (only for watchmedo script)

Licensing

Watchdog is licensed under the terms of the Apache License, version 2.0.

Copyright 2011 Yesudeep Mangalapilly.

Copyright 2012 Google, Inc & contributors.

Project source code is available at Github. Please report bugs and file enhancement requests at the issue tracker.

Why Watchdog?

Too many people tried to do the same thing and none did what I needed Python to do:

Comments
  • [0.9.0] Build fails on test

    [0.9.0] Build fails on test

    I see 2 problems:

    • First the test fails
    • The module is installed at the wrong location. Because it contains C/C++ code it mist be placed under /usr/lib64 but the installer will place it under /usr/lib/ witch is for python code only.

    here the build log:

    Executing(%prep): /bin/sh -e /var/tmp/rpm-tmp.TCew4J
    + umask 022
    + cd /builddir/build/BUILD
    + cd /builddir/build/BUILD
    + rm -rf watchdog-0.9.0
    + /usr/bin/gzip -dc /builddir/build/SOURCES/watchdog-0.9.0.tar.gz
    + /usr/bin/tar -xf -
    + STATUS=0
    + '[' 0 -ne 0 ']'
    + cd watchdog-0.9.0
    + /usr/bin/chmod -Rf a+rX,u+w,g-w,o-w .
    + rm -rf watchdog.egg-info
    + exit 0
    Executing(%build): /bin/sh -e /var/tmp/rpm-tmp.HU8XdO
    + umask 022
    + cd /builddir/build/BUILD
    + cd watchdog-0.9.0
    + CFLAGS='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches   -m64 -mtune=generic'
    + /usr/bin/python3.4 setup.py build '--executable=/usr/bin/python3.4 -s'
    running build
    running build_py
    creating build
    creating build/lib
    creating build/lib/watchdog
    copying src/watchdog/watchmedo.py -> build/lib/watchdog
    copying src/watchdog/version.py -> build/lib/watchdog
    copying src/watchdog/events.py -> build/lib/watchdog
    copying src/watchdog/__init__.py -> build/lib/watchdog
    creating build/lib/watchdog/utils
    copying src/watchdog/utils/win32stat.py -> build/lib/watchdog/utils
    copying src/watchdog/utils/unicode_paths.py -> build/lib/watchdog/utils
    copying src/watchdog/utils/platform.py -> build/lib/watchdog/utils
    copying src/watchdog/utils/importlib2.py -> build/lib/watchdog/utils
    copying src/watchdog/utils/event_backport.py -> build/lib/watchdog/utils
    copying src/watchdog/utils/echo.py -> build/lib/watchdog/utils
    copying src/watchdog/utils/dirsnapshot.py -> build/lib/watchdog/utils
    copying src/watchdog/utils/delayed_queue.py -> build/lib/watchdog/utils
    copying src/watchdog/utils/decorators.py -> build/lib/watchdog/utils
    copying src/watchdog/utils/compat.py -> build/lib/watchdog/utils
    copying src/watchdog/utils/bricks.py -> build/lib/watchdog/utils
    copying src/watchdog/utils/__init__.py -> build/lib/watchdog/utils
    creating build/lib/watchdog/tricks
    copying src/watchdog/tricks/__init__.py -> build/lib/watchdog/tricks
    creating build/lib/watchdog/observers
    copying src/watchdog/observers/winapi.py -> build/lib/watchdog/observers
    copying src/watchdog/observers/read_directory_changes.py -> build/lib/watchdog/observers
    copying src/watchdog/observers/polling.py -> build/lib/watchdog/observers
    copying src/watchdog/observers/kqueue.py -> build/lib/watchdog/observers
    copying src/watchdog/observers/inotify_c.py -> build/lib/watchdog/observers
    copying src/watchdog/observers/inotify_buffer.py -> build/lib/watchdog/observers
    copying src/watchdog/observers/inotify.py -> build/lib/watchdog/observers
    copying src/watchdog/observers/fsevents2.py -> build/lib/watchdog/observers
    copying src/watchdog/observers/fsevents.py -> build/lib/watchdog/observers
    copying src/watchdog/observers/api.py -> build/lib/watchdog/observers
    copying src/watchdog/observers/__init__.py -> build/lib/watchdog/observers
    running egg_info
    writing dependency_links to src/watchdog.egg-info/dependency_links.txt
    writing entry points to src/watchdog.egg-info/entry_points.txt
    writing top-level names to src/watchdog.egg-info/top_level.txt
    writing requirements to src/watchdog.egg-info/requires.txt
    writing src/watchdog.egg-info/PKG-INFO
    reading manifest file 'src/watchdog.egg-info/SOURCES.txt'
    reading manifest template 'MANIFEST.in'
    warning: no files found matching '*.h' under directory 'src'
    writing manifest file 'src/watchdog.egg-info/SOURCES.txt'
    + sleep 1
    + rm -rf html/.doctrees html/.buildinfo
    + exit 0
    Executing(%install): /bin/sh -e /var/tmp/rpm-tmp.8QiunX
    + umask 022
    + cd /builddir/build/BUILD
    + '[' /builddir/build/BUILDROOT/python-watchdog-0.9.0-1.el7.x86_64 '!=' / ']'
    + rm -rf /builddir/build/BUILDROOT/python-watchdog-0.9.0-1.el7.x86_64
    ++ dirname /builddir/build/BUILDROOT/python-watchdog-0.9.0-1.el7.x86_64
    + mkdir -p /builddir/build/BUILDROOT
    + mkdir /builddir/build/BUILDROOT/python-watchdog-0.9.0-1.el7.x86_64
    + cd watchdog-0.9.0
    + CFLAGS='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches   -m64 -mtune=generic'
    + /usr/bin/python3.4 setup.py install -O1 --skip-build --root /builddir/build/BUILDROOT/python-watchdog-0.9.0-1.el7.x86_64
    running install
    running install_lib
    creating /builddir/build/BUILDROOT/python-watchdog-0.9.0-1.el7.x86_64/usr
    creating /builddir/build/BUILDROOT/python-watchdog-0.9.0-1.el7.x86_64/usr/lib
    creating /builddir/build/BUILDROOT/python-watchdog-0.9.0-1.el7.x86_64/usr/lib/python3.4
    creating /builddir/build/BUILDROOT/python-watchdog-0.9.0-1.el7.x86_64/usr/lib/python3.4/site-packages
    creating /builddir/build/BUILDROOT/python-watchdog-0.9.0-1.el7.x86_64/usr/lib/python3.4/site-packages/watchdog
    creating /builddir/build/BUILDROOT/python-watchdog-0.9.0-1.el7.x86_64/usr/lib/python3.4/site-packages/watchdog/observers
    copying build/lib/watchdog/observers/__init__.py -> /builddir/build/BUILDROOT/python-watchdog-0.9.0-1.el7.x86_64/usr/lib/python3.4/site-packages/watchdog/observers
    copying build/lib/watchdog/observers/api.py -> /builddir/build/BUILDROOT/python-watchdog-0.9.0-1.el7.x86_64/usr/lib/python3.4/site-packages/watchdog/observers
    copying build/lib/watchdog/observers/fsevents.py -> /builddir/build/BUILDROOT/python-watchdog-0.9.0-1.el7.x86_64/usr/lib/python3.4/site-packages/watchdog/observers
    copying build/lib/watchdog/observers/fsevents2.py -> /builddir/build/BUILDROOT/python-watchdog-0.9.0-1.el7.x86_64/usr/lib/python3.4/site-packages/watchdog/observers
    copying build/lib/watchdog/observers/inotify.py -> /builddir/build/BUILDROOT/python-watchdog-0.9.0-1.el7.x86_64/usr/lib/python3.4/site-packages/watchdog/observers
    copying build/lib/watchdog/observers/inotify_buffer.py -> /builddir/build/BUILDROOT/python-watchdog-0.9.0-1.el7.x86_64/usr/lib/python3.4/site-packages/watchdog/observers
    copying build/lib/watchdog/observers/inotify_c.py -> /builddir/build/BUILDROOT/python-watchdog-0.9.0-1.el7.x86_64/usr/lib/python3.4/site-packages/watchdog/observers
    copying build/lib/watchdog/observers/kqueue.py -> /builddir/build/BUILDROOT/python-watchdog-0.9.0-1.el7.x86_64/usr/lib/python3.4/site-packages/watchdog/observers
    copying build/lib/watchdog/observers/polling.py -> /builddir/build/BUILDROOT/python-watchdog-0.9.0-1.el7.x86_64/usr/lib/python3.4/site-packages/watchdog/observers
    copying build/lib/watchdog/observers/read_directory_changes.py -> /builddir/build/BUILDROOT/python-watchdog-0.9.0-1.el7.x86_64/usr/lib/python3.4/site-packages/watchdog/observers
    copying build/lib/watchdog/observers/winapi.py -> /builddir/build/BUILDROOT/python-watchdog-0.9.0-1.el7.x86_64/usr/lib/python3.4/site-packages/watchdog/observers
    creating /builddir/build/BUILDROOT/python-watchdog-0.9.0-1.el7.x86_64/usr/lib/python3.4/site-packages/watchdog/tricks
    copying build/lib/watchdog/tricks/__init__.py -> /builddir/build/BUILDROOT/python-watchdog-0.9.0-1.el7.x86_64/usr/lib/python3.4/site-packages/watchdog/tricks
    creating /builddir/build/BUILDROOT/python-watchdog-0.9.0-1.el7.x86_64/usr/lib/python3.4/site-packages/watchdog/utils
    copying build/lib/watchdog/utils/__init__.py -> /builddir/build/BUILDROOT/python-watchdog-0.9.0-1.el7.x86_64/usr/lib/python3.4/site-packages/watchdog/utils
    copying build/lib/watchdog/utils/bricks.py -> /builddir/build/BUILDROOT/python-watchdog-0.9.0-1.el7.x86_64/usr/lib/python3.4/site-packages/watchdog/utils
    copying build/lib/watchdog/utils/compat.py -> /builddir/build/BUILDROOT/python-watchdog-0.9.0-1.el7.x86_64/usr/lib/python3.4/site-packages/watchdog/utils
    copying build/lib/watchdog/utils/decorators.py -> /builddir/build/BUILDROOT/python-watchdog-0.9.0-1.el7.x86_64/usr/lib/python3.4/site-packages/watchdog/utils
    copying build/lib/watchdog/utils/delayed_queue.py -> /builddir/build/BUILDROOT/python-watchdog-0.9.0-1.el7.x86_64/usr/lib/python3.4/site-packages/watchdog/utils
    copying build/lib/watchdog/utils/dirsnapshot.py -> /builddir/build/BUILDROOT/python-watchdog-0.9.0-1.el7.x86_64/usr/lib/python3.4/site-packages/watchdog/utils
    copying build/lib/watchdog/utils/echo.py -> /builddir/build/BUILDROOT/python-watchdog-0.9.0-1.el7.x86_64/usr/lib/python3.4/site-packages/watchdog/utils
    copying build/lib/watchdog/utils/event_backport.py -> /builddir/build/BUILDROOT/python-watchdog-0.9.0-1.el7.x86_64/usr/lib/python3.4/site-packages/watchdog/utils
    copying build/lib/watchdog/utils/importlib2.py -> /builddir/build/BUILDROOT/python-watchdog-0.9.0-1.el7.x86_64/usr/lib/python3.4/site-packages/watchdog/utils
    copying build/lib/watchdog/utils/platform.py -> /builddir/build/BUILDROOT/python-watchdog-0.9.0-1.el7.x86_64/usr/lib/python3.4/site-packages/watchdog/utils
    copying build/lib/watchdog/utils/unicode_paths.py -> /builddir/build/BUILDROOT/python-watchdog-0.9.0-1.el7.x86_64/usr/lib/python3.4/site-packages/watchdog/utils
    copying build/lib/watchdog/utils/win32stat.py -> /builddir/build/BUILDROOT/python-watchdog-0.9.0-1.el7.x86_64/usr/lib/python3.4/site-packages/watchdog/utils
    copying build/lib/watchdog/__init__.py -> /builddir/build/BUILDROOT/python-watchdog-0.9.0-1.el7.x86_64/usr/lib/python3.4/site-packages/watchdog
    copying build/lib/watchdog/events.py -> /builddir/build/BUILDROOT/python-watchdog-0.9.0-1.el7.x86_64/usr/lib/python3.4/site-packages/watchdog
    copying build/lib/watchdog/version.py -> /builddir/build/BUILDROOT/python-watchdog-0.9.0-1.el7.x86_64/usr/lib/python3.4/site-packages/watchdog
    copying build/lib/watchdog/watchmedo.py -> /builddir/build/BUILDROOT/python-watchdog-0.9.0-1.el7.x86_64/usr/lib/python3.4/site-packages/watchdog
    byte-compiling /builddir/build/BUILDROOT/python-watchdog-0.9.0-1.el7.x86_64/usr/lib/python3.4/site-packages/watchdog/observers/__init__.py to __init__.cpython-34.pyc
    byte-compiling /builddir/build/BUILDROOT/python-watchdog-0.9.0-1.el7.x86_64/usr/lib/python3.4/site-packages/watchdog/observers/api.py to api.cpython-34.pyc
    byte-compiling /builddir/build/BUILDROOT/python-watchdog-0.9.0-1.el7.x86_64/usr/lib/python3.4/site-packages/watchdog/observers/fsevents.py to fsevents.cpython-34.pyc
    byte-compiling /builddir/build/BUILDROOT/python-watchdog-0.9.0-1.el7.x86_64/usr/lib/python3.4/site-packages/watchdog/observers/fsevents2.py to fsevents2.cpython-34.pyc
    byte-compiling /builddir/build/BUILDROOT/python-watchdog-0.9.0-1.el7.x86_64/usr/lib/python3.4/site-packages/watchdog/observers/inotify.py to inotify.cpython-34.pyc
    byte-compiling /builddir/build/BUILDROOT/python-watchdog-0.9.0-1.el7.x86_64/usr/lib/python3.4/site-packages/watchdog/observers/inotify_buffer.py to inotify_buffer.cpython-34.pyc
    byte-compiling /builddir/build/BUILDROOT/python-watchdog-0.9.0-1.el7.x86_64/usr/lib/python3.4/site-packages/watchdog/observers/inotify_c.py to inotify_c.cpython-34.pyc
    byte-compiling /builddir/build/BUILDROOT/python-watchdog-0.9.0-1.el7.x86_64/usr/lib/python3.4/site-packages/watchdog/observers/kqueue.py to kqueue.cpython-34.pyc
    byte-compiling /builddir/build/BUILDROOT/python-watchdog-0.9.0-1.el7.x86_64/usr/lib/python3.4/site-packages/watchdog/observers/polling.py to polling.cpython-34.pyc
    byte-compiling /builddir/build/BUILDROOT/python-watchdog-0.9.0-1.el7.x86_64/usr/lib/python3.4/site-packages/watchdog/observers/read_directory_changes.py to read_directory_changes.cpython-34.pyc
    byte-compiling /builddir/build/BUILDROOT/python-watchdog-0.9.0-1.el7.x86_64/usr/lib/python3.4/site-packages/watchdog/observers/winapi.py to winapi.cpython-34.pyc
    byte-compiling /builddir/build/BUILDROOT/python-watchdog-0.9.0-1.el7.x86_64/usr/lib/python3.4/site-packages/watchdog/tricks/__init__.py to __init__.cpython-34.pyc
    byte-compiling /builddir/build/BUILDROOT/python-watchdog-0.9.0-1.el7.x86_64/usr/lib/python3.4/site-packages/watchdog/utils/__init__.py to __init__.cpython-34.pyc
    byte-compiling /builddir/build/BUILDROOT/python-watchdog-0.9.0-1.el7.x86_64/usr/lib/python3.4/site-packages/watchdog/utils/bricks.py to bricks.cpython-34.pyc
    byte-compiling /builddir/build/BUILDROOT/python-watchdog-0.9.0-1.el7.x86_64/usr/lib/python3.4/site-packages/watchdog/utils/compat.py to compat.cpython-34.pyc
    byte-compiling /builddir/build/BUILDROOT/python-watchdog-0.9.0-1.el7.x86_64/usr/lib/python3.4/site-packages/watchdog/utils/decorators.py to decorators.cpython-34.pyc
    byte-compiling /builddir/build/BUILDROOT/python-watchdog-0.9.0-1.el7.x86_64/usr/lib/python3.4/site-packages/watchdog/utils/delayed_queue.py to delayed_queue.cpython-34.pyc
    byte-compiling /builddir/build/BUILDROOT/python-watchdog-0.9.0-1.el7.x86_64/usr/lib/python3.4/site-packages/watchdog/utils/dirsnapshot.py to dirsnapshot.cpython-34.pyc
    byte-compiling /builddir/build/BUILDROOT/python-watchdog-0.9.0-1.el7.x86_64/usr/lib/python3.4/site-packages/watchdog/utils/echo.py to echo.cpython-34.pyc
    byte-compiling /builddir/build/BUILDROOT/python-watchdog-0.9.0-1.el7.x86_64/usr/lib/python3.4/site-packages/watchdog/utils/event_backport.py to event_backport.cpython-34.pyc
    byte-compiling /builddir/build/BUILDROOT/python-watchdog-0.9.0-1.el7.x86_64/usr/lib/python3.4/site-packages/watchdog/utils/importlib2.py to importlib2.cpython-34.pyc
    byte-compiling /builddir/build/BUILDROOT/python-watchdog-0.9.0-1.el7.x86_64/usr/lib/python3.4/site-packages/watchdog/utils/platform.py to platform.cpython-34.pyc
    byte-compiling /builddir/build/BUILDROOT/python-watchdog-0.9.0-1.el7.x86_64/usr/lib/python3.4/site-packages/watchdog/utils/unicode_paths.py to unicode_paths.cpython-34.pyc
    byte-compiling /builddir/build/BUILDROOT/python-watchdog-0.9.0-1.el7.x86_64/usr/lib/python3.4/site-packages/watchdog/utils/win32stat.py to win32stat.cpython-34.pyc
    byte-compiling /builddir/build/BUILDROOT/python-watchdog-0.9.0-1.el7.x86_64/usr/lib/python3.4/site-packages/watchdog/__init__.py to __init__.cpython-34.pyc
    byte-compiling /builddir/build/BUILDROOT/python-watchdog-0.9.0-1.el7.x86_64/usr/lib/python3.4/site-packages/watchdog/events.py to events.cpython-34.pyc
    byte-compiling /builddir/build/BUILDROOT/python-watchdog-0.9.0-1.el7.x86_64/usr/lib/python3.4/site-packages/watchdog/version.py to version.cpython-34.pyc
    byte-compiling /builddir/build/BUILDROOT/python-watchdog-0.9.0-1.el7.x86_64/usr/lib/python3.4/site-packages/watchdog/watchmedo.py to watchmedo.cpython-34.pyc
    writing byte-compilation script '/tmp/tmpyiqk3hge.py'
    /usr/bin/python3.4 -O /tmp/tmpyiqk3hge.py
    removing /tmp/tmpyiqk3hge.py
    running install_egg_info
    running egg_info
    writing dependency_links to src/watchdog.egg-info/dependency_links.txt
    writing entry points to src/watchdog.egg-info/entry_points.txt
    writing requirements to src/watchdog.egg-info/requires.txt
    writing src/watchdog.egg-info/PKG-INFO
    writing top-level names to src/watchdog.egg-info/top_level.txt
    reading manifest file 'src/watchdog.egg-info/SOURCES.txt'
    reading manifest template 'MANIFEST.in'
    warning: no files found matching '*.h' under directory 'src'
    writing manifest file 'src/watchdog.egg-info/SOURCES.txt'
    Copying src/watchdog.egg-info to /builddir/build/BUILDROOT/python-watchdog-0.9.0-1.el7.x86_64/usr/lib/python3.4/site-packages/watchdog-0.9.0-py3.4.egg-info
    running install_scripts
    Installing watchmedo script to /builddir/build/BUILDROOT/python-watchdog-0.9.0-1.el7.x86_64/usr/bin
    + /usr/lib/rpm/find-debuginfo.sh --strict-build-id -m --run-dwz --dwz-low-mem-die-limit 10000000 --dwz-max-die-limit 110000000 /builddir/build/BUILD/watchdog-0.9.0
    /usr/lib/rpm/sepdebugcrcfix: Updated 0 CRC32s, 0 CRC32s did match.
    find: 'debug': No such file or directory
    + /usr/lib/rpm/check-buildroot
    + /usr/lib/rpm/redhat/brp-compress
    + /usr/lib/rpm/redhat/brp-strip-static-archive /usr/bin/strip
    + /usr/lib/rpm/brp-python-bytecompile /usr/bin/python 1
    + /usr/lib/rpm/redhat/brp-python-hardlink
    + /usr/lib/rpm/redhat/brp-java-repack-jars
    Executing(%check): /bin/sh -e /var/tmp/rpm-tmp.ou8A87
    + umask 022
    + cd /builddir/build/BUILD
    + cd watchdog-0.9.0
    + /usr/bin/python3.4 setup.py test
    running test
    running egg_info
    writing entry points to src/watchdog.egg-info/entry_points.txt
    writing requirements to src/watchdog.egg-info/requires.txt
    writing top-level names to src/watchdog.egg-info/top_level.txt
    writing src/watchdog.egg-info/PKG-INFO
    writing dependency_links to src/watchdog.egg-info/dependency_links.txt
    reading manifest file 'src/watchdog.egg-info/SOURCES.txt'
    reading manifest template 'MANIFEST.in'
    warning: no files found matching '*.h' under directory 'src'
    writing manifest file 'src/watchdog.egg-info/SOURCES.txt'
    running build_ext
    Traceback (most recent call last):
      File "setup.py", line 167, in <module>
        zip_safe=False
      File "/usr/lib64/python3.4/distutils/core.py", line 148, in setup
        dist.run_commands()
      File "/usr/lib64/python3.4/distutils/dist.py", line 955, in run_commands
        self.run_command(cmd)
      File "/usr/lib64/python3.4/distutils/dist.py", line 974, in run_command
        cmd_obj.run()
      File "/usr/lib/python3.4/site-packages/setuptools/command/test.py", line 159, in run
        self.with_project_on_sys_path(self.run_tests)
      File "/usr/lib/python3.4/site-packages/setuptools/command/test.py", line 140, in with_project_on_sys_path
        func()
      File "setup.py", line 77, in run_tests
        errno = pytest.main(self.test_args)
      File "/usr/lib/python3.4/site-packages/_pytest/config.py", line 38, in main
        config = _prepareconfig(args, plugins)
      File "/usr/lib/python3.4/site-packages/_pytest/config.py", line 117, in _prepareconfig
        pluginmanager=pluginmanager, args=args)
      File "/usr/lib/python3.4/site-packages/_pytest/vendored_packages/pluggy.py", line 724, in __call__
        return self._hookexec(self, self._nonwrappers + self._wrappers, kwargs)
      File "/usr/lib/python3.4/site-packages/_pytest/vendored_packages/pluggy.py", line 338, in _hookexec
        return self._inner_hookexec(hook, methods, kwargs)
      File "/usr/lib/python3.4/site-packages/_pytest/vendored_packages/pluggy.py", line 333, in <lambda>
        _MultiCall(methods, kwargs, hook.spec_opts).execute()
      File "/usr/lib/python3.4/site-packages/_pytest/vendored_packages/pluggy.py", line 595, in execute
        return _wrapped_call(hook_impl.function(*args), self.execute)
      File "/usr/lib/python3.4/site-packages/_pytest/vendored_packages/pluggy.py", line 249, in _wrapped_call
        wrap_controller.send(call_outcome)
      File "/usr/lib/python3.4/site-packages/_pytest/helpconfig.py", line 28, in pytest_cmdline_parse
        config = outcome.get_result()
      File "/usr/lib/python3.4/site-packages/_pytest/vendored_packages/pluggy.py", line 278, in get_result
        raise ex[1].with_traceback(ex[2])
      File "/usr/lib/python3.4/site-packages/_pytest/vendored_packages/pluggy.py", line 264, in __init__
        self.result = func()
      File "/usr/lib/python3.4/site-packages/_pytest/vendored_packages/pluggy.py", line 596, in execute
        res = hook_impl.function(*args)
      File "/usr/lib/python3.4/site-packages/_pytest/config.py", line 852, in pytest_cmdline_parse
        self.parse(args)
      File "/usr/lib/python3.4/site-packages/_pytest/config.py", line 957, in parse
        self._preparse(args)
      File "/usr/lib/python3.4/site-packages/_pytest/config.py", line 918, in _preparse
        self.pluginmanager.load_setuptools_entrypoints("pytest11")
      File "/usr/lib/python3.4/site-packages/_pytest/vendored_packages/pluggy.py", line 504, in load_setuptools_entrypoints
        self.register(plugin, name=ep.name)
      File "/usr/lib/python3.4/site-packages/_pytest/config.py", line 207, in register
        ret = super(PytestPluginManager, self).register(plugin, name)
      File "/usr/lib/python3.4/site-packages/_pytest/vendored_packages/pluggy.py", line 370, in register
        hook._maybe_apply_history(hookimpl)
      File "/usr/lib/python3.4/site-packages/_pytest/vendored_packages/pluggy.py", line 747, in _maybe_apply_history
        res = self._hookexec(self, [method], kwargs)
      File "/usr/lib/python3.4/site-packages/_pytest/vendored_packages/pluggy.py", line 338, in _hookexec
        return self._inner_hookexec(hook, methods, kwargs)
      File "/usr/lib/python3.4/site-packages/_pytest/vendored_packages/pluggy.py", line 333, in <lambda>
        _MultiCall(methods, kwargs, hook.spec_opts).execute()
      File "/usr/lib/python3.4/site-packages/_pytest/vendored_packages/pluggy.py", line 596, in execute
        res = hook_impl.function(*args)
      File "/usr/lib/python3.4/site-packages/pytest_timeout.py", line 65, in pytest_addoption
        parser.addini('timeout_func_only', FUNC_ONLY_DESC, type='bool')
      File "/usr/lib/python3.4/site-packages/_pytest/config.py", line 510, in addini
        assert type in (None, "pathlist", "args", "linelist")
    AssertionError
    
    opened by tuxmaster5000 31
  • Support coalesced `fsevents`

    Support coalesced `fsevents`

    Starting this as a draft PR to get some early feedback.

    The general idea is to expose an is_coalesced property on NativeEvent instances. This allows the NativeEvent -> FileSystemEvent conversion to perform additional checks on NativeEvent.path if necessary. With these additional checks the NativeEvent -> FileSystemEvent mechanism then has a chance to execute "a chain of properly sorted if-clauses instead of if-else clauses".

    Do note that in case of coalesced events it is impossible to know how many times NativeEvent.path was created, removed or renamed. It is only possible to know that such an event occurred at least once within an fseventsd update interval.

    @SamSchott - please let me know if you think the list of "coalesced event" bit masks is sufficient or not. As far as I can imagine right now then the tricky bits with coalesced events are around creation, removal, and rename of an item in an observed path.

    fsevents-c 
    opened by CCP-Aporia 25
  • 'pip install watchdog' fails on macOS 10.15.2 Catalina

    'pip install watchdog' fails on macOS 10.15.2 Catalina

    pip install watchdog fails after I upgraded to macOS 10.15.2 with this error:

        Complete output (202 lines):
        running install
        running build
        running build_py
        creating build
        creating build/lib.macosx-10.14-x86_64-3.5
        creating build/lib.macosx-10.14-x86_64-3.5/watchdog
        copying src/watchdog/watchmedo.py -> build/lib.macosx-10.14-x86_64-3.5/watchdog
        copying src/watchdog/version.py -> build/lib.macosx-10.14-x86_64-3.5/watchdog
        copying src/watchdog/events.py -> build/lib.macosx-10.14-x86_64-3.5/watchdog
        copying src/watchdog/__init__.py -> build/lib.macosx-10.14-x86_64-3.5/watchdog
        creating build/lib.macosx-10.14-x86_64-3.5/watchdog/utils
        copying src/watchdog/utils/unicode_paths.py -> build/lib.macosx-10.14-x86_64-3.5/watchdog/utils
        copying src/watchdog/utils/compat.py -> build/lib.macosx-10.14-x86_64-3.5/watchdog/utils
        copying src/watchdog/utils/win32stat.py -> build/lib.macosx-10.14-x86_64-3.5/watchdog/utils
        copying src/watchdog/utils/__init__.py -> build/lib.macosx-10.14-x86_64-3.5/watchdog/utils
        copying src/watchdog/utils/dirsnapshot.py -> build/lib.macosx-10.14-x86_64-3.5/watchdog/utils
        copying src/watchdog/utils/delayed_queue.py -> build/lib.macosx-10.14-x86_64-3.5/watchdog/utils
        copying src/watchdog/utils/platform.py -> build/lib.macosx-10.14-x86_64-3.5/watchdog/utils
        copying src/watchdog/utils/bricks.py -> build/lib.macosx-10.14-x86_64-3.5/watchdog/utils
        copying src/watchdog/utils/echo.py -> build/lib.macosx-10.14-x86_64-3.5/watchdog/utils
        creating build/lib.macosx-10.14-x86_64-3.5/watchdog/observers
        copying src/watchdog/observers/fsevents.py -> build/lib.macosx-10.14-x86_64-3.5/watchdog/observers
        copying src/watchdog/observers/inotify.py -> build/lib.macosx-10.14-x86_64-3.5/watchdog/observers
        copying src/watchdog/observers/__init__.py -> build/lib.macosx-10.14-x86_64-3.5/watchdog/observers
        copying src/watchdog/observers/api.py -> build/lib.macosx-10.14-x86_64-3.5/watchdog/observers
        copying src/watchdog/observers/inotify_buffer.py -> build/lib.macosx-10.14-x86_64-3.5/watchdog/observers
        copying src/watchdog/observers/winapi.py -> build/lib.macosx-10.14-x86_64-3.5/watchdog/observers
        copying src/watchdog/observers/read_directory_changes.py -> build/lib.macosx-10.14-x86_64-3.5/watchdog/observers
        copying src/watchdog/observers/kqueue.py -> build/lib.macosx-10.14-x86_64-3.5/watchdog/observers
        copying src/watchdog/observers/inotify_c.py -> build/lib.macosx-10.14-x86_64-3.5/watchdog/observers
        copying src/watchdog/observers/polling.py -> build/lib.macosx-10.14-x86_64-3.5/watchdog/observers
        copying src/watchdog/observers/fsevents2.py -> build/lib.macosx-10.14-x86_64-3.5/watchdog/observers
        creating build/lib.macosx-10.14-x86_64-3.5/watchdog/tricks
        copying src/watchdog/tricks/__init__.py -> build/lib.macosx-10.14-x86_64-3.5/watchdog/tricks
        running egg_info
        writing top-level names to src/watchdog.egg-info/top_level.txt
        writing requirements to src/watchdog.egg-info/requires.txt
        writing src/watchdog.egg-info/PKG-INFO
        writing entry points to src/watchdog.egg-info/entry_points.txt
        writing dependency_links to src/watchdog.egg-info/dependency_links.txt
        reading manifest file 'src/watchdog.egg-info/SOURCES.txt'
        reading manifest template 'MANIFEST.in'
        warning: no files found matching '*.h' under directory 'src'
        writing manifest file 'src/watchdog.egg-info/SOURCES.txt'
        running build_ext
        building '_watchdog_fsevents' extension
        creating build/temp.macosx-10.14-x86_64-3.5
        creating build/temp.macosx-10.14-x86_64-3.5/src
        clang -Wno-unused-result -Wsign-compare -Wunreachable-code -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -I/Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/usr/include -DWATCHDOG_VERSION_STRING="0.10.0" -DWATCHDOG_VERSION_MAJOR=0 -DWATCHDOG_VERSION_MINOR=10 -DWATCHDOG_VERSION_BUILD=0 -I/Users/ericvanegmond/.pyenv/versions/3.5.3/include/python3.5m -c src/watchdog_fsevents.c -o build/temp.macosx-10.14-x86_64-3.5/src/watchdog_fsevents.o -std=c99 -pedantic -Wall -Werror -Wextra -fPIC -Wno-error=unused-command-line-argument
        In file included from src/watchdog_fsevents.c:22:
        In file included from /Users/ericvanegmond/.pyenv/versions/3.5.3/include/python3.5m/Python.h:25:
        In file included from /Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/usr/include/stdio.h:64:
        /Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/usr/include/_stdio.h:137:9: error: type nullability specifier '_Nullable' is a Clang extension [-Werror,-Wnullability-extension]
                int     (* _Nullable _close)(void *);
                           ^
        /Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/usr/include/_stdio.h:93:16: error: pointer is missing a nullability type specifier (_Nonnull, _Nullable, or _Null_unspecified) [-Werror,-Wnullability-completeness]
                unsigned char   *_base;
                                ^
        /Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/usr/include/_stdio.h:93:16: note: insert '_Nullable' if the pointer may be null
                unsigned char   *_base;
                                ^
                                  _Nullable
    .
    .
    .
        /Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/usr/include/stdio.h:391:44: note: insert '_Nullable' if the pointer may be null
                         fpos_t (* _Nullable)(void *, fpos_t, int),
                                                   ^
                                                    _Nullable
        /Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/usr/include/stdio.h:391:44: note: insert '_Nonnull' if the pointer should never be null
                         fpos_t (* _Nullable)(void *, fpos_t, int),
                                                   ^
                                                    _Nonnull
        /Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/usr/include/stdio.h:392:25: error: type nullability specifier '_Nullable' is a Clang extension [-Werror,-Wnullability-extension]
                         int (* _Nullable)(void *));
                                ^
        fatal error: too many errors emitted, stopping now [-ferror-limit=]
        20 errors generated.
        error: command 'clang' failed with exit status 1
        ----------------------------------------
    

    Any suggestions on how to resolve this? So far I've tried removing and reinstalling both xcode and command line tools which hasn't helped. Not sure what else to try here.

    bug 
    opened by ericve25 23
  • Release cycle

    Release cycle

    @danilobellini what do you think to publish releases more often? For instance there are several bug fixes in the current unreleased version. Perhaps could you publish a 0.9.1 with those changes?

    documentation 
    opened by BoboTiG 21
  • Modifed event triggered twice

    Modifed event triggered twice

    if I copy and paste a file on OSX lion it triggered created event once and modified event twice should it be just trigger once modified event?

    INFO:root:Created file: /Users/ouyangjichao/BoxSync/rename/testwatchdog.py INFO:root:Modified file: /Users/ouyangjichao/BoxSync/rename/testwatchdog.py INFO:root:Modified file: /Users/ouyangjichao/BoxSync/rename/testwatchdog.py

    fsevents-c 
    opened by jcouyang 21
  • second install of watchdog on non-macos incorrectly requires darwin dependencies

    second install of watchdog on non-macos incorrectly requires darwin dependencies

    If I run pip install watchdog on a clean python environment it works fine and doesn't install the pyobjc dependencies, although pip does output what look like warnings or errors:

    watchdog 0.10.0 requires pyobjc-framework-Cocoa>=4.2.2, which is not installed.
    watchdog 0.10.0 requires pyobjc-framework-FSEvents>=4.2.2, which is not installed.
    

    If I run pip install watchdog again pip does see it as already installed but then tries to install the pyobjc dependencies and fails. Here's the full command output:

    (_venv) [email protected]:~/py3$ python --version
    Python 3.6.9
    (_venv) [email protected]:~/py3$ pip install watchdog
    Collecting watchdog
      Using cached https://files.pythonhosted.org/packages/01/01/cc9b2fd111e19687dd42155f066718bccb414c8a728eb7df0b229742caf7/watchdog-0.10.0.tar.gz
      Ignoring pyobjc-framework-Cocoa: markers 'sys_platform == "darwin"' don't match your environment
      Ignoring pyobjc-framework-FSEvents: markers 'sys_platform == "darwin"' don't match your environment
    Collecting pathtools>=0.1.1 (from watchdog)
      Using cached https://files.pythonhosted.org/packages/e7/7f/470d6fcdf23f9f3518f6b0b76be9df16dcc8630ad409947f8be2eb0ed13a/pathtools-0.1.2.tar.gz
    Building wheels for collected packages: watchdog, pathtools
      Running setup.py bdist_wheel for watchdog ... done
      Stored in directory: /home/vagrant/.cache/pip/wheels/d4/74/90/4e0d4d5050776ce9a03e8a2c873e523b0149bf6412546dfc3f
      Running setup.py bdist_wheel for pathtools ... done
      Stored in directory: /home/vagrant/.cache/pip/wheels/0b/04/79/c3b0c3a0266a3cb4376da31e5bfe8bba0c489246968a68e843
    Successfully built watchdog pathtools
    watchdog 0.10.0 requires pyobjc-framework-Cocoa>=4.2.2, which is not installed.
    watchdog 0.10.0 requires pyobjc-framework-FSEvents>=4.2.2, which is not installed.
    Installing collected packages: pathtools, watchdog
    Successfully installed pathtools-0.1.2 watchdog-0.10.0
    You are using pip version 18.0, however version 20.0.2 is available.
    You should consider upgrading via the 'pip install --upgrade pip' command.
    (_venv) [email protected]:~/py3$ pip install watchdog
    Requirement already satisfied: watchdog in ./_venv/lib/python3.6/site-packages (0.10.0)
    Requirement already satisfied: pathtools>=0.1.1 in ./_venv/lib/python3.6/site-packages (from watchdog) (0.1.2)
    Collecting pyobjc-framework-Cocoa>=4.2.2 (from watchdog)
      Downloading https://files.pythonhosted.org/packages/7a/99/bfac679ee346f344bca72ee315249e56f4f34bc974345f66d7810380ce7a/pyobjc-framework-Cocoa-6.1.tar.gz (3.9MB)
        100% |████████████████████████████████| 3.9MB 4.1MB/s
        Complete output from command python setup.py egg_info:
        Traceback (most recent call last):
          File "<string>", line 1, in <module>
          File "/tmp/pip-install-vnyl8c9t/pyobjc-framework-Cocoa/setup.py", line 25, in <module>
            extra_link_args=["-framework", "CoreFoundation"],
          File "/tmp/pip-install-vnyl8c9t/pyobjc-framework-Cocoa/pyobjc_setup.py", line 408, in Extension
            os_level = get_os_level()
          File "/tmp/pip-install-vnyl8c9t/pyobjc-framework-Cocoa/pyobjc_setup.py", line 218, in get_os_level
            pl = plistlib.readPlist("/System/Library/CoreServices/SystemVersion.plist")
          File "/usr/lib/python3.6/plistlib.py", line 162, in readPlist
            with _maybe_open(pathOrFile, 'rb') as fp:
          File "/usr/lib/python3.6/contextlib.py", line 81, in __enter__
            return next(self.gen)
          File "/usr/lib/python3.6/plistlib.py", line 120, in _maybe_open
            with open(pathOrFile, mode) as fp:
        FileNotFoundError: [Errno 2] No such file or directory: '/System/Library/CoreServices/SystemVersion.plist'
    
        ----------------------------------------
    Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-install-vnyl8c9t/pyobjc-framework-Cocoa/
    You are using pip version 18.0, however version 20.0.2 is available.
    You should consider upgrading via the 'pip install --upgrade pip' command.
    

    I have tested this with python 2.7 and 3.6 and the behavior is the same.

    Additionally, if you try installing while the wheel version is cached, you also get the same error, even if watchdog is not installed:

    (_venv) [email protected]:~/py3$ pip install watchdog
    Processing /home/vagrant/.cache/pip/wheels/d4/74/90/4e0d4d5050776ce9a03e8a2c873e523b0149bf6412546dfc3f/watchdog-0.10.0-cp36-none-any.whl
    Collecting pyobjc-framework-FSEvents>=4.2.2
      Downloading pyobjc-framework-FSEvents-6.1.tar.gz (24 kB)
        ERROR: Command errored out with exit status 1:
         command: /home/vagrant/py3/_venv/bin/python3 -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-2slm3k7e/pyobjc-framework-FSEvents/setup.py'"'"'; __file__='"'"'/tmp/pip-install-2slm3k7e/pyobjc-framework-FSEvents/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' egg_info --egg-base /tmp/pip-install-2slm3k7e/pyobjc-framework-FSEvents/pip-egg-info
             cwd: /tmp/pip-install-2slm3k7e/pyobjc-framework-FSEvents/
        Complete output (15 lines):
        Traceback (most recent call last):
          File "<string>", line 1, in <module>
          File "/tmp/pip-install-2slm3k7e/pyobjc-framework-FSEvents/setup.py", line 20, in <module>
            ext_modules=[Extension("FSEvents._callbacks", ["Modules/_callbacks.m"])],
          File "/tmp/pip-install-2slm3k7e/pyobjc-framework-FSEvents/pyobjc_setup.py", line 408, in Extension
            os_level = get_os_level()
          File "/tmp/pip-install-2slm3k7e/pyobjc-framework-FSEvents/pyobjc_setup.py", line 218, in get_os_level
            pl = plistlib.readPlist("/System/Library/CoreServices/SystemVersion.plist")
          File "/usr/lib/python3.6/plistlib.py", line 162, in readPlist
            with _maybe_open(pathOrFile, 'rb') as fp:
          File "/usr/lib/python3.6/contextlib.py", line 81, in __enter__
            return next(self.gen)
          File "/usr/lib/python3.6/plistlib.py", line 120, in _maybe_open
            with open(pathOrFile, mode) as fp:
        FileNotFoundError: [Errno 2] No such file or directory: '/System/Library/CoreServices/SystemVersion.plist'
        ----------------------------------------
    ERROR: Command errored out with exit status 1: python setup.py egg_info Check the logs for full command output.
    

    Upgrading to the latest pip (20.0.2) exhibits the same error.

    bug 
    opened by reversefold 20
  • watchmedo shell-command: drop events during execution of command

    watchmedo shell-command: drop events during execution of command

    (original title): watchmedo shell-command --wait seems to fire more often than necessary

    Version: watchdog 0.6.0

    When I execute the watchmedo script with "--wait --command=..." seems to be triggered to often. The command seems to be executed for each detected event according to the generated command-output. This seems to unnecessary and inefficient. Normally, I would expect the following behavior

    # -- PSEUDO-CODE:
    loop forever:
        Wait until event occurs.
        Remove all pending events (from the scheduler queue).
        Execute the command (once for all removed/pending events)
    

    REASON: When the command is executed it should rebuild whatever and be responsible for all accumulated events.

    The efficient behaviour could also be enabled by a new, additional command-line option.

    NOTE: If you do not use the "--wait" option you can still use the nice debug/diag feature:

    watchmedo shell-command ... --command='echo "${watch_src_path}"'
    

    to detect which filesystem events occurred.

    watchmedo feature 
    opened by jenisys 20
  • Fixes missing notification for deletion of watched dir on macOS

    Fixes missing notification for deletion of watched dir on macOS

    This PR fixes an issue which would prevent us from being notified when the watched directory is deleted. This is achieved by passing the kFSEventStreamCreateFlagWatchRoot to the watch.

    bug fsevents-c 
    opened by samschott 19
  • [WIP] FSEventsEmitter order events by mtime

    [WIP] FSEventsEmitter order events by mtime

    This is an updated version, similar to the somewhat outdated PR #311. This essentially orders emitted events by mtime and prevents confusion when FileDeletedEvents and FileCreatedEvents appear out of order. This would fix for instance #538.

    This issue only appears when using DirectorySnapshot to poll for events, as FSEventsEmitter does, and therefore does not seem to affect most observers.

    Let me know if this is the right place to fix this, or if a modification of DirectorySnapshot is more appropriate.

    opened by samschott 19
  • Installation of pyobjc-Core makes watchdog unusable on non MacOS hardware

    Installation of pyobjc-Core makes watchdog unusable on non MacOS hardware

    Collecting pyobjc-core==6.1
    
      Downloading https://artifactory.us-east-1.bamgrid.net/api/pypi/dataengineering-pypi/packages/packages/3a/80/0cdb2130b86a984e4765beb93135aa9c2120fd64be1a27e1c7cb31c719bc/pyobjc-core-6.1.tar.gz (791 kB)
    
        ERROR: Command errored out with exit status 1:
    
         command: /databricks/python3/bin/python3.7 -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-09k75p2e/pyobjc-core/setup.py'"'"'; __file__='"'"'/tmp/pip-install-09k75p2e/pyobjc-core/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' --no-user-cfg egg_info --egg-base /tmp/pip-install-09k75p2e/pyobjc-core/pip-egg-info
    
             cwd: /tmp/pip-install-09k75p2e/pyobjc-core/
    
        Complete output (2 lines):
    
        running egg_info
    
        error: PyObjC requires macOS to build
    
        ----------------------------------------
    
    ERROR: Command errored out with exit status 1: python setup.py egg_info Check the logs for full command output.
    
    script returned exit code 1
    
    
    bug 
    opened by jperkelens 18
  • SEGFAULT on macOS with the latest version of watchdog

    SEGFAULT on macOS with the latest version of watchdog

    Unfortunately, this will be tough to describe, since I don't have a mac and only my CI is complaining.

    I'm using watchdog as a submodule and today tried to update it. One specific test consistently makes pytest segfault.

    This is the log from a SEGFAULTING run: https://dev.azure.com/borisstaletic/3ce92110-caa5-4c49-b8c3-44a433da676b/_apis/build/builds/1535/logs/64 The way I'm using watchdog is by talking to, in this case, jdt.ls. When I open this file it sends... these patterns:

    [
      {
        "globPattern": "**/*.java"
      },
      {
        "globPattern": "**/.project"
      },
      {
        "globPattern": "**/.classpath"
      },
      {
        "globPattern": "**/.settings/*.prefs"
      },
      {
        "globPattern": "**/src/**"
      },
      {
        "globPattern": "**/*.gradle"
      },
      {
        "globPattern": "**/gradle.properties"
      },
      {
        "globPattern": "**/pom.xml"
      },
      {
        "globPattern": "/home/bstaletic/work/ycmd/ycmd/tests/java/testdata/simple_eclipse_project",
        "kind": 4
      }
    ]
    

    Which we then edit, like this: https://github.com/ycm-core/ycmd/blob/master/ycmd/completers/language_server/language_server_completer.py#L590-L591

    And finally use that with this handler: https://github.com/ycm-core/ycmd/blob/master/ycmd/completers/language_server/language_server_completer.py#L3219

    Any further information, as well as running the CI, I can gladly provide.

    bug fsevents-c PR welcome :) 
    opened by bstaletic 17
  • BUG on latest version on Windows

    BUG on latest version on Windows

    $ watchmedo auto-restart --patterns="*.py;langs.json" --recursive -- python -c "import core;core.ampalibe.init.run()" 
    failed to create process
    

    with the old version it works, but with the last no

    opened by gaetan1903 4
  • Wrong events when observer started on old Windows SMB1 shares

    Wrong events when observer started on old Windows SMB1 shares

    Dear all,

    I'm facing a very strange problem, that is to say: as soon as the emitter starts, a directory delete event with src_path targeting the observer base path is triggered.

    This is happening only when the monitored folder is a shared folder from an old WinXP machine still using the SMB1.

    Can you have a look at that?

    I'm using watchdog 2.2.0 on windows.

    Thanks

    opened by abulgher 1
  • LoggingEventHandler is not triggered for files copied using SCP

    LoggingEventHandler is not triggered for files copied using SCP

    Hello, I have the simple code below monitoring an NFS mounted directory (/homes/myname/subdir). The host is a CentOS7.9 system.

    If I manually create a file by using touch (e.g: touch /homes/myname/subdir/a.txt) the event registers with LoggingEventHandler and I can see the output.

    But when I copy a large file (~500MB) to the same directory I don't see any response from LoggingEventHandler. I found the same behavior with FileSystemEventHandler, PatternMatchingEventHandler. They respond when I log into the CentOS system and touch a file to create it. But when a scp copies the file (large or small) to the same directory it is not caught by watchdog.

    from watchdog.observers import Observer
    from watchdog.events import LoggingEventHandler
    import argparse
    import logging
    import time
        
    if __name__ == "__main__":
        parser = argparse.ArgumentParser(description="Push new executables from CL folders to Nexus")
        parser.add_argument("--dir",help="Directory containing CL folders",required=True)
        args = parser.parse_args()
    
        logging.basicConfig(level=logging.INFO,
                            format='%(asctime)s - %(message)s',
                            datefmt='%Y-%m-%d %H:%M:%S')
    
        event_handler = LoggingEventHandler()
        observer = Observer()
        observer.schedule(event_handler, path=args.dir, recursive=True)
        logging.info("Monitoring started")
        observer.start()
    
        try:
            while observer.is_alive():
                time.sleep(1)
        except KeyboardInterrupt:
            logging.error("Process Killed by Ctrl+C")
            observer.stop()
            observer.join()
        finally:
            observer.stop()
            observer.join()
    
    

    Here is the output when I manually create the file by touching it on the CentOS system.

    myneni/[email protected]:50:15> cd /homes/homer3b/myneni/prog/py/push2nexus ; /usr/bin/env /homes/homp2n/bin/python /homes/homer3b/myneni/.vscode-server/extensions/ms-python.python-2022.18.2/py/../debugpy/launcher 45501 -- /homes/homer3b/myneni/prog/py/push2nexus/push2nexus.py --dir /homes/homer3a/osqa/ca_os_binaries 
    2022-11-15 22:51:11 - Monitoring started
    2022-11-15 22:51:19 - Created file: /homes/homer3a/osqa/ca_os_binaries/209900/osbla.tmp
    2022-11-15 22:51:19 - Modified directory: /homes/homer3a/osqa/ca_os_binaries/209900
    2022-11-15 22:51:19 - Modified file: /homes/homer3a/osqa/ca_os_binaries/209900/osbla.tmp
    2022-11-15 22:51:19 - Modified directory: /homes/homer3a/osqa/ca_os_binaries/209900
    2022-11-15 22:51:25 - Deleted file: /homes/homer3a/osqa/ca_os_binaries/209900/osbla.tmp
    2022-11-15 22:51:25 - Modified directory: /homes/homer3a/osqa/ca_os_binaries/209900
    

    I don't see this kind of behavior when the file is created by scp (same code as above).

    opened by sachinmyneni 0
  • Custom tricks cannot inspect their target directories

    Custom tricks cannot inspect their target directories

    It would be very helpful if pathname was passed to the TrickClass constructor by watchmedo: https://github.com/gorakhargosh/watchdog/blob/21e9f4c6466b884f87ab39d704101fb4b8b9f3c6/src/watchdog/watchmedo.py#L206

    Without this, a Trick subclass cannot do directory inspection prior to the .dispatch(...) loop kicking off, eg, to set its internal state on restart or similar.

    watchmedo PR welcome :) improvement 
    opened by brianthelion 2
  • watchmedo auto-restart behavior change with 2.1.9

    watchmedo auto-restart behavior change with 2.1.9

    We were using watchmedo auto-restart to call mypy and some flake8 tooling upon file changes. With the changes introduced by https://github.com/gorakhargosh/watchdog/pull/896, these processes re-run continually every time they exit whereas before they were re-ran upon a watched file/directory change.

    The name auto-restart makes me believe that this is actually desirable behavior and perhaps we were misusing that sub-command, however there doesn't appear to be an alternative to get the behavior we once had. watchmedo shell-command only runs the command on change with no option to run it once and also upon watched file change.

    Is there a way to add a flag to auto-restart which only restarts on an exit code, or maybe a way to use shell-command to call the command initially and then repeat on a file change?

    watchmedo feature PR welcome :) 
    opened by jaycle 0
  • watchmedo argument to set shell to something other than /bin/sh

    watchmedo argument to set shell to something other than /bin/sh

    Currently the executable argument is not passed. A literal is shown in the example below but I believe this should default to /bin/sh and allow an override through an argument. Of course sh can start bash too but this seems wasteful.

    subprocess.Popen(comman, shell=True, executable='/bin/bash')

    opened by jogomu 1
Releases(v2.2.1)
  • v2.2.1(Jan 1, 2023)

    • Enable mypy to discover type hints as specified in PEP 561 (#933)
    • [ci] Set the expected Python version when building release files
    • [ci] Update actions versions in use
    • [watchmedo] [regression] Fix usage of missing signal.SIGHUP attribute on non-Unix OSes (#935)

    :heart_decoration: Thanks to our beloved contributors: @BoboTiG, @simon04, @piotrpdev

    Source code(tar.gz)
    Source code(zip)
  • v2.2.0(Dec 5, 2022)

    • [build] Wheels are now available for Python 3.11 (#932)
    • [documentation] HTML documentation builds are now tested for errors (#902)
    • [documentation] Fix typos here, and there (#910)
    • [fsevents2] The fsevents2 observer is now deprecated (#909)
    • [tests] The error message returned by musl libc for error code -1 is now allowed (#923)
    • [utils] Remove unnecessary code in dirsnapshot.py (#930)
    • [watchmedo] Handle shutdown events from SIGHUP (#912)

    :heart_decoration: Thanks to our beloved contributors: @kurtmckee, @babymastodon, @QuantumEnergyE, @timgates42, @BoboTiG

    Source code(tar.gz)
    Source code(zip)
  • v2.1.6(Oct 1, 2021)

    • [bsd] Fixed returned paths in kqueue.py and restored the overall results of the test suite. (#842)
    • [bsd] Updated FreeBSD CI support .(#841)
    • [watchmedo] Removed the argh dependency in favor of the builtin argparse module. (#836)
    • [watchmedo] Removed unexistant WindowsApiAsyncObserver references and --debug-force-winapi-async arguments.
    • [watchmedo] Improved the help output.

    :heart_decoration: Thanks to our beloved contributors: @knobix, @AndreaRe9, @BoboTiG

    Source code(tar.gz)
    Source code(zip)
  • v2.1.9(Jun 10, 2022)

    • [fsevents] Fix flakey test to assert that there are no errors when stopping the emitter.
    • [inotify] Suppress occasional OSError: [Errno 9] Bad file descriptor at shutdown. #805
    • [watchmedo] Make auto-restart restart the sub-process if it terminates. #896
    • [watchmedo] Avoid zombie sub-processes when running shell-command without --wait. #405

    :heart_decoration: Thanks to our beloved contributors: @samschott, @taleinat, @altendky, @BoboTiG

    Source code(tar.gz)
    Source code(zip)
  • v2.1.8(May 15, 2022)

    • Fix adding failed emitters on observer schedule. (#872)
    • [inotify] Fix hang when unscheduling watch on a path in an unmounted filesystem. (#869)
    • [watchmedo] Fix broken parsing of --kill-after argument for the auto-restart command. (#870)
    • [watchmedo] Fix broken parsing of boolean arguments. (#887)
    • [watchmedo] Fix broken parsing of commands from auto-restart, and shell-command. (#888)
    • [watchmedo] Support setting verbosity level via -q/--quiet and -v/--verbose arguments. (#889)

    :heart_decoration: Thanks to our beloved contributors: @taleinat, @kianmeng, @palfrey, @IlayRosenberg, @BoboTiG

    Source code(tar.gz)
    Source code(zip)
  • v2.1.7(Mar 25, 2022)

    • Eliminate timeout in waiting on event queue. (#861)
    • [inotify] Fix not equality implementation for InotifyEvent. (#848)
    • [watchmedo] Fix calling commands from within a Python script. (#879)
    • [watchmedo] PyYAML is loaded only when strictly necessary. Simple usages of watchmedo are possible without the module being installed. (#847)

    :heart_decoration: Thanks to our beloved contributors: @sattlerc, @JanzenLiu, @BoboTiG

    Source code(tar.gz)
    Source code(zip)
  • v2.1.5(Aug 23, 2021)

    • Fix regression introduced in 2.1.4 (reverted "Allow overriding or adding custom event handlers to event dispatch map. (#814)"). (#830)
    • Convert regexes of type str to list. (#831)

    :heart_decoration: Thanks to our beloved contributors: @unique1o1, @BoboTiG

    Source code(tar.gz)
    Source code(zip)
  • v2.1.4(Aug 19, 2021)

    • [watchmedo] Fix usage of os.setsid() and os.killpg() Unix-only functions. (#809)
    • [mac] Fix missing FileModifiedEvent on permission or ownership changes of a file. (#815)
    • [mac] Convert absolute watch path in FSEeventsEmitter with os.path.realpath(). (#822)
    • Fix a possible AttributeError in SkipRepeatsQueue._put(). (#818)
    • Allow overriding or adding custom event handlers to event dispatch map. (#814)
    • Fix tests on big endian platforms. (#828)

    :heart_decoration: Thanks to our beloved contributors: @replabrobin, @BoboTiG, @SamSchott, @AndreiB97, @NiklasRosenstein, @ikokollari, @mgorny

    Source code(tar.gz)
    Source code(zip)
  • v0.10.7(Jul 5, 2021)

    • Avoid crashing the event processing thread on non-utf8 filenames (#811)
    • [backport 1.0.0] [mac] Regression fixes for native fsevents (#717)
    • [backport 1.0.0] [windows] winapi.BUFFER_SIZE now defaults to 64000 (instead of 2048) (#700)
    • [backport 1.0.0] [windows] Introduced winapi.PATH_BUFFER_SIZE (defaults to 2048) to keep the old behavior with path-realted functions (#700)
    • [backport 1.0.0] Removed the long-time deprecated events.LoggingFileSystemEventHandler class, use LoggingEventHandler instead
    • [backport 1.0.2] Wheels are published for GNU/Linux, macOS and Windows (#739)
    • [backport 1.0.2] [mac] Fix missing event_id attribute in fsevents (#721)
    • [backport 1.0.2] [mac] Return byte paths if a byte path was given in fsevents (#726`)
    • [backport 1.0.2] [mac] Add compatibility with old macOS versions (#733`)
    • [backport 1.0.2] Uniformize event for deletion of watched dir (#727)
    • [backport 2.0.0] [inotify] Add support for IN_CLOSE_WRITE events. A FileCloseEvent event will be fired. Note that IN_CLOSE_NOWRITE events are not handled to prevent much noise. (#184, #245,#280, #313,#690)
    • [backport 2.0.0] [mac] Support coalesced filesystem events (#734)
    • [backport 2.0.0] [mac] Drop support for OSX 10.12 and earlier (#750)
    • [backport 2.0.0] [mac] Fix an issue when renaming an item changes only the casing (#750)
    • Thanks to our beloved contributors: @SamSchott, @bstaletic, @BoboTiG, @CCP-Aporia, @di, @lukassup, @ysard, @lovasoa
    Source code(tar.gz)
    Source code(zip)
  • v2.1.3(Jun 26, 2021)

  • v2.1.2(May 19, 2021)

    • [mac] Fix relative path handling for non-recursive watch. (#797)
    • [windows] On PyPy, events happening right after start() were missed. Add a workaround for that. (#796)
    • Thanks to our beloved contributors: @oprypin, @CCP-Aporia, @BoboTiG
    Source code(tar.gz)
    Source code(zip)
  • v2.1.1(May 10, 2021)

    • [mac] Fix callback exceptions when the watcher is deleted but still receiving events (#786)
    • Thanks to our beloved contributors: @rom1win, @BoboTiG, @CCP-Aporia
    Source code(tar.gz)
    Source code(zip)
  • v2.1.0(May 4, 2021)

    • [inotify] Simplify libc loading (#776)
    • [mac] Add support for non-recursive watches in FSEventsEmitter (#779)
    • [watchmedo] Add support for --debug-force-* arguments to tricks (#781)
    • Thanks to our beloved contributors: @CCP-Aporia, @aodj, @UnitedMarsupials, @BoboTiG
    Source code(tar.gz)
    Source code(zip)
  • v2.0.3(Apr 22, 2021)

    • [mac] Use logger.debug() instead of logger.info() (#774)
    • Updated documentation links (#777)
    • Thanks to our beloved contributors: @globau, @imba-tjd, @BoboTiG
    Source code(tar.gz)
    Source code(zip)
  • v2.0.2(Feb 22, 2021)

  • v2.0.1(Feb 20, 2021)

    • [mac] Fix a segmentation fault when dealing with unicode paths (#763)
    • Moved the CI from Travis-CI to GitHub Actions (#764)
    • Thanks to our beloved contributors: @SamSchott, @BoboTiG
    Source code(tar.gz)
    Source code(zip)
  • v2.0.0(Feb 11, 2021)

    • ⚠️ [mac] Drop support for macOS 10.12 and earlier (#750)
    • [mac] Support coalesced filesystem events (#734)
    • [mac] Fix an issue when renaming an item changes only the casing (#750)
    • [inotify] Add support for IN_CLOSE_WRITE events. A FileCloseEvent event will be fired. Note that IN_CLOSE_NOWRITE events are not handled to prevent much noise. (#184, #245, #280, #313, #690)
    • [inotify] Allow to stop the emitter multiple times (#760)
    • Avoid deprecated PyEval_InitThreads on Python 3.7+ (#746)
    • Thanks to our beloved contributors: @bstaletic, @lukassup, @ysard, @SamSchott, @CCP-Aporia, @BoboTiG
    Source code(tar.gz)
    Source code(zip)
  • v1.0.2(Dec 18, 2020)

    • Wheels are published for GNU/Linux, macOS and Windows (#739)
    • [mac] Fix missing event_id attribute in fsevents (#721)
    • [mac] Return byte paths if a byte path was given in fsevents (#726)
    • [mac] Add compatibility with old macOS versions (#733)
    • Uniformize event for deletion of watched dir (#727)
    • Thanks to our beloved contributors: @SamSchott, @CCP-Aporia, @di, @BoboTiG
    Source code(tar.gz)
    Source code(zip)
  • v1.0.0(Dec 10, 2020)

    • Versioning is now following the semver
    • Drop support for Python 2.7, 3.4 and 3.5
    • [mac] Regression fixes for native fsevents (#717)
    • [windows] winapi.BUFFER_SIZE now defaults to 64000 (instead of 2048) (#700)
    • [windows] Introduced winapi.PATH_BUFFER_SIZE (defaults to 2048) to keep the old behavior with path-realted functions (#700)
    • Use pathlib from the standard library, instead of pathtools (#556)
    • Allow file paths on Unix that don't follow the file system encoding (#703)
    • Removed the long-time deprecated events.LoggingFileSystemEventHandler class, use LoggingEventHandler instead
    • Thanks to our beloved contributors: @SamSchott, @bstaletic, @BoboTiG, @CCP-Aporia
    Source code(tar.gz)
    Source code(zip)
  • v0.10.5(Dec 10, 2020)

  • v0.10.4(Nov 21, 2020)

    • Add logger parameter for the LoggingEventHandler (#676)
    • Replace mutable default arguments with if None implementation in RegexMatchingEventHandler (#677)
    • Expand tests to Python 2.7 and 3.5-3.10 for GNU/Linux, macOS and Windows
    • [mac] Performance improvements for the fsevents module (#680)
    • [mac] Prevent compilation of watchdog_fsevents.c on non-macOS machines (#687)
    • [watchmedo] Handle shutdown events from SIGTERM and SIGINT more reliably (#693)
    • Thanks to our beloved contributors: @Sraw, @CCP-Aporia, @BoboTiG, @maybe-sybr
    Source code(tar.gz)
    Source code(zip)
  • v0.10.3(Jun 25, 2020)

    • Ensure ObservedWatch.path is a string (#651)
    • [inotify] Allow to monitor single file (#655)
    • [inotify] Prevent raising an exception when a file in a monitored folder has no permissions (#669, #670)
    • Thanks to our beloved contributors: @brant-ruan, @rec, @andfoy, @BoboTiG
    Source code(tar.gz)
    Source code(zip)
  • v0.10.2(Feb 8, 2020)

    • Fixed the build_ext command on macOS Catalina (#628)
    • Fixed the installation of macOS requirements on non-macOS OSes (#635)
    • Refactored dispatch() method of FileSystemEventHandler, PatternMatchingEventHandler and RegexMatchingEventHandler
    • bsd] Improved tests support on non Windows/Linux platforms (#633, #639)
    • [bsd] Added FreeBSD CI support (#532)
    • [bsd] Restored full support (#638, #641)
    • Thanks to our beloved contributors: @BoboTiG, @evilham, @danilobellini
    Source code(tar.gz)
    Source code(zip)
  • v0.10.1(Jan 31, 2020)

    • Fixed Python 2.7 to 3.6 installation when the OS locale is set to POSIX (#615)
    • Fixed the build_ext command on macOS (#618, #620)
    • Moved requirements to setup.cfg (#617)
    • [mac] Removed old C code for Python 2.5 in the fsevents C implementation
    • [snapshot] Added EmptyDirectorySnapshot (#613)
    • Thanks to our beloved contributors: @Ajordat, @tehkirill, @BoboTiG
    Source code(tar.gz)
    Source code(zip)
  • v0.10.0(Jan 26, 2020)

    2020-01-26 • full history

    Breaking changes

    • Dropped support for Python 2.6, 3.2 and 3.3
    • Emitters that failed to start are now removed
    • [snapshot] Removed the deprecated walker_callback argument, use stat instead
    • [watchmedo] The utility is no more installed by default but via the extra watchdog[watchmedo]

    Other Changes

    • Fixed several Python 3 warnings
    • Identify synthesized events with is_synthetic attribute (#369)
    • Use os.scandir() to improve memory usage (#503)
    • [bsd] Fixed flavors of FreeBSD detection (#529)
    • [bsd] Skip unprocessable socket files (#509)
    • [inotify] Fixed events containing non-ASCII characters (#516)
    • [inotify] Fixed the way OSError are re-raised (#377)
    • [inotify] Fixed wrong source path after renaming a top level folder (#515)
    • [inotify] Removed delay from non-move events (#477)
    • [mac] Fixed a bug when calling FSEventsEmitter.stop() twice (#466)
    • [mac] Support for unscheduling deleted watch (#541)
    • [mac] Fixed missing field initializers and unused parameters in watchdog_fsevents.c
    • [snapshot] Don't walk directories without read permissions (#408)
    • [snapshot] Fixed a race condition crash when a directory is swapped for a file (#513)
    • [snasphot] Fixed an AttributeError about forgotten path_for_inode attr (#436)
    • [snasphot] Added the ignore_device=False parameter to the ctor (#597)
    • [watchmedo] Fixed the path separator used (#478)
    • [watchmedo] Fixed the use of yaml.load() for yaml.safe_load() (#453)
    • [watchmedo] Handle all available signals (#549)
    • [watchmedo] Added the --debug-force-polling argument (#404)
    • [windows] Fixed issues when the observed directory is deleted (#570 and #601)
    • [windows] WindowsApiEmitter made easier to subclass (#344)
    • [windows] Use separate ctypes DLL instances
    • [windows] Generate sub created events only if recursive=True (#454)
    • Thanks to our beloved contributors: @BoboTiG, @LKleinNux, @rrzaripov, @wildmichael, @TauPan, @segevfiner, @petrblahos, @QuantumEnergyE, @jeffwidman, @kapsh, @nickoala, @petrblahos, @julianolf, @tonybaloney, @mbakiev, @pR0Ps, @javaguirre, @skurfer, @exarkun, @joshuaskelly, @danilobellini, @Ajordat
    Source code(tar.gz)
    Source code(zip)
  • v0.9.0(Dec 12, 2019)

    2018-08-28 • full history

    • Deleting the observed directory now emits a DirDeletedEvent event
    • [bsd] Improved the platform detection (#378)
    • [inotify] Fixed a crash when the root directory being watched by was deleted (#374)
    • [inotify] Handle systems providing uClibc
    • [linux] Fixed a possible DirDeletedEvent duplication when deleting a directory
    • [mac] Fixed unicode path handling fsevents2.py (#298)
    • [watchmedo] Added the --debug-force-polling argument (#336)
    • [windows] Fixed the FILE_LIST_DIRECTORY constant (#376)
    • Thanks to our beloved contributors: @vulpeszerda, @hpk42, @tamland, @senden9, @gorakhargosh, @nolsto, @mafrosis, @DonyorM, @anthrotype, @danilobellini, @pierregr, @ShinNoNoir, @adrpar, @gforcada, @pR0Ps, @yegorich, @dhke
    Source code(tar.gz)
    Source code(zip)
  • v0.8.3(Dec 12, 2019)

    2015-02-11 • full history

    • Fixed the use of the root logger (#274)
    • [inotify] Refactored libc loading and improved error handling in inotify_c.py
    • [inotify] Fixed a possible unbound local error in inotify_c.py
    • Thanks to our beloved contributors: @mmorearty, @tamland, @tony, @gorakhargosh
    Source code(tar.gz)
    Source code(zip)
  • v0.8.2(Dec 12, 2019)

    2014-10-29 • full history

    • Event emitters are no longer started on schedule if Observer is not already running
    • [mac] Fixed usued arguments to pass clang compilation (#265)
    • [snapshot] Fixed a possible race condition crash on directory deletion (#281)
    • [windows] Fixed an error when watching the same folder again (#270)
    • Thanks to our beloved contributors: @tamland, @apetrone, @Falldog, @theospears
    Source code(tar.gz)
    Source code(zip)
  • v0.8.1(Dec 12, 2019)

  • v0.8.0(Dec 12, 2019)

    2014-07-02 • full history

    • Fixed argh deprecation warnings (#242)
    • [snapshot] Methods returning internal stats info were replaced by mtime(), inode() and path() methods
    • [snapshot] Deprecated the walker_callback argument
    • [watchmedo] Fixed auto-restart to terminate all children processes (#225)
    • [watchmedo] Added the --no-parallel argument (#227)
    • [windows] Fixed the value of INVALID_HANDLE_VALUE (#123)
    • [windows] Fixed octal usages to work with Python 3 as well (#223)
    • Thanks to our beloved contributors: @tamland, @Ormod, @berdario, @cro, @BernieSumption, @pypingou, @gotcha, @tommorris, @frewsxcv
    Source code(tar.gz)
    Source code(zip)
CredSweeper is a tool to detect credentials in any directories or files.

CredSweeper is a tool to detect credentials in any directories or files. CredSweeper could help users to detect unwanted exposure of credentials (such as personal information, token, passwords, api k

Samsung 54 Dec 13, 2022
Python module that parse power builder file (PBD) and analyze code

PowerBuilder-decompile Python module that parse power builder file (PBD) and analyze code (Incomplete) this tool is composed of: pbd_dump.py pbd file

Samy Sultan 8 Dec 15, 2022
A tiny Python library for writing multi-channel TIFF stacks.

xtiff A tiny Python library for writing multi-channel TIFF stacks. The aim of this library is to provide an easy way to write multi-channel image stac

23 Dec 27, 2022
Python library and shell utilities to monitor filesystem events.

Watchdog Python API and shell utilities to monitor file system events. Works on 3.6+. If you want to use Python 2.6, you should stick with watchdog

Yesudeep Mangalapilly 5.6k Jan 04, 2023
PyDeleter - delete a specifically formatted file in a directory or delete all other files

PyDeleter If you want to delete a specifically formatted file in a directory or delete all other files, PyDeleter does it for you. How to use? 1- Down

Amirabbas Motamedi 1 Jan 30, 2022
Dragon Age: Origins toolset to extract/build .erf files, patch language-specific .dlg files, and view the contents of files in the ERF or GFF format

DAOTools This is a set of tools for Dragon Age: Origins modding. It can patch the text lines of .dlg files, extract and build an .erf file, and view t

8 Dec 06, 2022
Simple, convenient and cross-platform file date changing library. 📝📅

Simple, convenient and cross-platform file date changing library.

kubinka0505 15 Dec 18, 2022
Swiss army knife for Apple's .tbd file manipulation

Description Inspired by tbdswizzler, this simple python tool for manipulating Apple's .tbd format. Installation python3 -m pip install --user -U pytbd

10 Aug 31, 2022
Uncompress DEFLATE streams in pure Python

stream-inflate Uncompress DEFLATE streams in pure Python. Installation pip install stream-inflate Usage from stream_inflate import stream_inflate impo

Michal Charemza 7 Oct 13, 2022
Kartothek - a Python library to manage large amounts of tabular data in a blob store

Kartothek - a Python library to manage (create, read, update, delete) large amounts of tabular data in a blob store

15 Dec 25, 2022
ValveVMF - A python library to parse Valve's VMF files

ValveVMF ValveVMF is a Python library for parsing .vmf files for the Source Engi

pySourceSDK 2 Jan 02, 2022
Yadl - it is a simple library for working with both dotenv files and environment variables.

Yadl Yadl - it is a simple library for working with both dotenv files and environment variables. Features Validation of whitespaces. Validation of num

Ivan Kapranov 3 Oct 19, 2021
CleverCSV is a Python package for handling messy CSV files.

CleverCSV is a Python package for handling messy CSV files. It provides a drop-in replacement for the builtin CSV module with improved dialect detection, and comes with a handy command line applicati

The Alan Turing Institute 1k Dec 19, 2022
Convert CSV files into a SQLite database

csvs-to-sqlite Convert CSV files into a SQLite database. Browse and publish that SQLite database with Datasette. Basic usage: csvs-to-sqlite myfile.cs

Simon Willison 731 Dec 27, 2022
Python virtual filesystem for SQLite to read from and write to S3

Python virtual filesystem for SQLite to read from and write to S3

Department for International Trade 70 Jan 04, 2023
A platform independent file lock for Python

py-filelock This package contains a single module, which implements a platform independent file lock in Python, which provides a simple way of inter-p

Benedikt Schmitt 497 Jan 05, 2023
Read and write TIFF files

Read and write TIFF files Tifffile is a Python library to store numpy arrays in TIFF (Tagged Image File Format) files, and read image and metadata fro

Christoph Gohlke 346 Dec 18, 2022
An easy-to-use library for emulating code in minidump files.

dumpulator Note: This is a work-in-progress prototype, please treat it as such. An easy-to-use library for emulating code in minidump files. Example T

Duncan Ogilvie 362 Dec 31, 2022
Python code snippets for extracting PDB codes from .fasta files

Python_snippets_for_bioinformatics Python code snippets for extracting PDB codes from .fasta files If you have a single .fasta file for all protein se

Sofi-Mukhtar 3 Feb 09, 2022
The best way to convert files on your computer, be it .pdf to .png, .pdf to .docx, .png to .ico, or anything you can imagine.

The best way to convert files on your computer, be it .pdf to .png, .pdf to .docx, .png to .ico, or anything you can imagine.

JareBear 2 Nov 20, 2021