Hello community,

here is the log from the commit of package python3-pyinotify for 
openSUSE:Factory checked in at 2015-01-12 09:49:50
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python3-pyinotify (Old)
 and      /work/SRC/openSUSE:Factory/.python3-pyinotify.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python3-pyinotify"

Changes:
--------
--- /work/SRC/openSUSE:Factory/python3-pyinotify/python3-pyinotify.changes      
2013-06-21 19:01:55.000000000 +0200
+++ /work/SRC/openSUSE:Factory/.python3-pyinotify.new/python3-pyinotify.changes 
2015-01-12 09:49:51.000000000 +0100
@@ -1,0 +2,29 @@
+Sat Jan 10 18:00:31 UTC 2015 - [email protected]
+
+- specfile:
+  * update copyright year
+  * update source url to pypi
+
+- update to version 0.9.5 (taken from git log):
+  * Implement stop method in AsyncioNotifier
+  * Remove extra lines, fix indents
+  * Update pyinotify.py
+  * Allow TornadoAsyncNotifier.stop() to clean up all hanging refs.
+  * doc update
+  * Add asyncio example
+  * Add asyncio Notifier adapter
+  * Fix ExcludeFilter docstring examples.
+  * Add new classifiers.
+  * Typo.
+  * Improve example daemon.py.
+  * Stub support for Pyinotify on FreeBSD.
+  * Add WatchManager attribute to ignore events.
+  * Fix /proc inotify interfaces.
+  * Update Travis conf.
+  * Handle OSError exception in process_IN_CREATE.
+  * Add python-3.3 to travis
+  * py-2.5 removed as per 
http://about.travis-ci.org/blog/2013-11-18-upcoming-build-environment-updates/
+  * add glob option to command line
+  * Fall back to glob.glob() on Python 2.4
+
+-------------------------------------------------------------------

Old:
----
  pyinotify-0.9.4.tar.gz

New:
----
  pyinotify-0.9.5.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python3-pyinotify.spec ++++++
--- /var/tmp/diff_new_pack.zumeZo/_old  2015-01-12 09:49:52.000000000 +0100
+++ /var/tmp/diff_new_pack.zumeZo/_new  2015-01-12 09:49:52.000000000 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package python3-pyinotify
 #
-# Copyright (c) 2013 SUSE LINUX Products GmbH, Nuernberg, Germany.
+# Copyright (c) 2015 SUSE LINUX Products GmbH, Nuernberg, Germany.
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -17,14 +17,13 @@
 
 
 Name:           python3-pyinotify
-Version:        0.9.4
+Version:        0.9.5
 Release:        0
 Summary:        Python module for watching filesystems changes
 License:        MIT
 Group:          Development/Libraries/Python
 Url:            http://github.com/seb-m/pyinotify
-# downloaded from https://github.com/seb-m/pyinotify/tags
-Source:         pyinotify-%{version}.tar.gz
+Source:         
https://pypi.python.org/packages/source/p/pyinotify/pyinotify-%{version}.tar.gz
 Source1:        pyinotify
 BuildRequires:  python3
 BuildRequires:  python3-devel

++++++ pyinotify-0.9.4.tar.gz -> pyinotify-0.9.5.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyinotify-0.9.4/.gitignore 
new/pyinotify-0.9.5/.gitignore
--- old/pyinotify-0.9.4/.gitignore      2012-11-15 19:39:22.000000000 +0100
+++ new/pyinotify-0.9.5/.gitignore      1970-01-01 01:00:00.000000000 +0100
@@ -1,15 +0,0 @@
-# General ignore rules
-
-*.kpf
-*.o
-*.pyc
-*.a
-*~
-\#*
-*.log
-*.tmp
-*.bak
-a.out
-*.out
-docstrings/
-build/
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyinotify-0.9.4/.travis.yml 
new/pyinotify-0.9.5/.travis.yml
--- old/pyinotify-0.9.4/.travis.yml     2012-11-15 19:39:22.000000000 +0100
+++ new/pyinotify-0.9.5/.travis.yml     1970-01-01 01:00:00.000000000 +0100
@@ -1,9 +0,0 @@
-language: python
-python:
-  - "2.4"
-  - "2.5"
-  - "2.6"
-  - "2.7"
-  - "3.2"
-  - "pypy"
-script: /bin/true
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyinotify-0.9.4/PKG-INFO new/pyinotify-0.9.5/PKG-INFO
--- old/pyinotify-0.9.4/PKG-INFO        1970-01-01 01:00:00.000000000 +0100
+++ new/pyinotify-0.9.5/PKG-INFO        2015-01-09 22:49:28.000000000 +0100
@@ -0,0 +1,33 @@
+Metadata-Version: 1.1
+Name: pyinotify
+Version: 0.9.5
+Summary: Linux filesystem events monitoring
+Home-page: http://github.com/seb-m/pyinotify
+Author: Sebastien Martini
+Author-email: [email protected]
+License: MIT License
+Download-URL: http://pypi.python.org/pypi/pyinotify
+Description: UNKNOWN
+Platform: Linux
+Classifier: Development Status :: 5 - Production/Stable
+Classifier: Environment :: Console
+Classifier: Intended Audience :: Developers
+Classifier: License :: OSI Approved :: MIT License
+Classifier: Natural Language :: English
+Classifier: Operating System :: POSIX :: Linux
+Classifier: Programming Language :: Python
+Classifier: Programming Language :: Python :: 2.4
+Classifier: Programming Language :: Python :: 2.5
+Classifier: Programming Language :: Python :: 2.6
+Classifier: Programming Language :: Python :: 2.7
+Classifier: Programming Language :: Python :: 3
+Classifier: Programming Language :: Python :: 3.0
+Classifier: Programming Language :: Python :: 3.1
+Classifier: Programming Language :: Python :: 3.2
+Classifier: Programming Language :: Python :: 3.3
+Classifier: Programming Language :: Python :: 3.4
+Classifier: Programming Language :: Python :: Implementation :: CPython
+Classifier: Programming Language :: Python :: Implementation :: PyPy
+Classifier: Topic :: Software Development :: Libraries :: Python Modules
+Classifier: Topic :: System :: Filesystems
+Classifier: Topic :: System :: Monitoring
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyinotify-0.9.4/python2/examples/daemon.py 
new/pyinotify-0.9.5/python2/examples/daemon.py
--- old/pyinotify-0.9.4/python2/examples/daemon.py      2012-11-15 
19:39:22.000000000 +0100
+++ new/pyinotify-0.9.5/python2/examples/daemon.py      2014-07-10 
20:51:42.000000000 +0200
@@ -35,14 +35,18 @@
 
 # Notifier instance spawns a new process when daemonize is set to True. This
 # child process' PID is written to /tmp/pyinotify.pid (it also automatically
-# deletes it when it exits normally). If no custom pid_file is provided it
-# would write it more traditionally under /var/run/. Note that in both cases
-# the caller must ensure the pid file doesn't exist when this method is called
-# othewise it will raise an exception. /tmp/stdout.txt is used as stdout 
-# stream thus traces of events will be written in it. callback is the above 
-# function and will be called after each event loop.
+# deletes it when it exits normally). Note that this tmp location is just for
+# the sake of the example to avoid requiring administrative rights in order
+# to run this example. But by default if no explicit pid_file parameter is
+# provided it will default to its more traditional location under /var/run/.
+# Note that in both cases the caller must ensure the pid file doesn't exist
+# before this method is called otherwise it will raise an exception.
+# /tmp/pyinotify.log is used as log file to dump received events. Likewise
+# in your real code choose a more appropriate location for instance under
+# /var/log (this file may contain sensitive data). Finally, callback is the
+# above function and will be called after each event loop.
 try:
     notifier.loop(daemonize=True, callback=on_loop_func,
-                  pid_file='/tmp/pyinotify.pid', stdout='/tmp/stdout.txt')
+                  pid_file='/tmp/pyinotify.pid', stdout='/tmp/pyinotify.log')
 except pyinotify.NotifierError, err:
     print >> sys.stderr, err
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyinotify-0.9.4/python2/pyinotify.egg-info/PKG-INFO 
new/pyinotify-0.9.5/python2/pyinotify.egg-info/PKG-INFO
--- old/pyinotify-0.9.4/python2/pyinotify.egg-info/PKG-INFO     1970-01-01 
01:00:00.000000000 +0100
+++ new/pyinotify-0.9.5/python2/pyinotify.egg-info/PKG-INFO     2015-01-09 
22:49:27.000000000 +0100
@@ -0,0 +1,33 @@
+Metadata-Version: 1.1
+Name: pyinotify
+Version: 0.9.5
+Summary: Linux filesystem events monitoring
+Home-page: http://github.com/seb-m/pyinotify
+Author: Sebastien Martini
+Author-email: [email protected]
+License: MIT License
+Download-URL: http://pypi.python.org/pypi/pyinotify
+Description: UNKNOWN
+Platform: Linux
+Classifier: Development Status :: 5 - Production/Stable
+Classifier: Environment :: Console
+Classifier: Intended Audience :: Developers
+Classifier: License :: OSI Approved :: MIT License
+Classifier: Natural Language :: English
+Classifier: Operating System :: POSIX :: Linux
+Classifier: Programming Language :: Python
+Classifier: Programming Language :: Python :: 2.4
+Classifier: Programming Language :: Python :: 2.5
+Classifier: Programming Language :: Python :: 2.6
+Classifier: Programming Language :: Python :: 2.7
+Classifier: Programming Language :: Python :: 3
+Classifier: Programming Language :: Python :: 3.0
+Classifier: Programming Language :: Python :: 3.1
+Classifier: Programming Language :: Python :: 3.2
+Classifier: Programming Language :: Python :: 3.3
+Classifier: Programming Language :: Python :: 3.4
+Classifier: Programming Language :: Python :: Implementation :: CPython
+Classifier: Programming Language :: Python :: Implementation :: PyPy
+Classifier: Topic :: Software Development :: Libraries :: Python Modules
+Classifier: Topic :: System :: Filesystems
+Classifier: Topic :: System :: Monitoring
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pyinotify-0.9.4/python2/pyinotify.egg-info/SOURCES.txt 
new/pyinotify-0.9.5/python2/pyinotify.egg-info/SOURCES.txt
--- old/pyinotify-0.9.4/python2/pyinotify.egg-info/SOURCES.txt  1970-01-01 
01:00:00.000000000 +0100
+++ new/pyinotify-0.9.5/python2/pyinotify.egg-info/SOURCES.txt  2015-01-09 
22:49:28.000000000 +0100
@@ -0,0 +1,34 @@
+ACKS
+COPYING
+MANIFEST.in
+README.md
+setup.py
+common/inotify_syscalls.c
+old/ChangeLog
+old/NEWS
+python2/Makefile
+python2/pyinotify.py
+python2/examples/autocompile.py
+python2/examples/chain.py
+python2/examples/coalesce.py
+python2/examples/daemon.py
+python2/examples/exclude.lst
+python2/examples/exclude.py
+python2/examples/loop.py
+python2/examples/not_quiet.py
+python2/examples/stats.py
+python2/examples/stats_threaded.py
+python2/examples/tornado_notifier.py
+python2/examples/transient_file.py
+python2/examples/transient_file.sh
+python2/examples/tutorial_asyncnotifier.py
+python2/examples/tutorial_notifier.py
+python2/examples/tutorial_threadednotifier.py
+python2/examples/unicode.py
+python2/pyinotify.egg-info/PKG-INFO
+python2/pyinotify.egg-info/SOURCES.txt
+python2/pyinotify.egg-info/dependency_links.txt
+python2/pyinotify.egg-info/top_level.txt
+python3/Makefile
+python3/pyinotify.py
+python3/examples/asyncio_notifier.py
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pyinotify-0.9.4/python2/pyinotify.egg-info/dependency_links.txt 
new/pyinotify-0.9.5/python2/pyinotify.egg-info/dependency_links.txt
--- old/pyinotify-0.9.4/python2/pyinotify.egg-info/dependency_links.txt 
1970-01-01 01:00:00.000000000 +0100
+++ new/pyinotify-0.9.5/python2/pyinotify.egg-info/dependency_links.txt 
2015-01-09 22:49:27.000000000 +0100
@@ -0,0 +1 @@
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pyinotify-0.9.4/python2/pyinotify.egg-info/top_level.txt 
new/pyinotify-0.9.5/python2/pyinotify.egg-info/top_level.txt
--- old/pyinotify-0.9.4/python2/pyinotify.egg-info/top_level.txt        
1970-01-01 01:00:00.000000000 +0100
+++ new/pyinotify-0.9.5/python2/pyinotify.egg-info/top_level.txt        
2015-01-09 22:49:27.000000000 +0100
@@ -0,0 +1 @@
+pyinotify
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyinotify-0.9.4/python2/pyinotify.py 
new/pyinotify-0.9.5/python2/pyinotify.py
--- old/pyinotify-0.9.4/python2/pyinotify.py    2012-11-15 19:39:22.000000000 
+0100
+++ new/pyinotify-0.9.5/python2/pyinotify.py    2015-01-09 22:13:04.000000000 
+0100
@@ -1,7 +1,7 @@
 #!/usr/bin/env python
 
 # pyinotify.py - python interface to inotify
-# Copyright (c) 2005-2011 Sebastien Martini <[email protected]>
+# Copyright (c) 2005-2015 Sebastien Martini <[email protected]>
 #
 # Permission is hereby granted, free of charge, to any person obtaining a copy
 # of this software and associated documentation files (the "Software"), to deal
@@ -68,7 +68,6 @@
 import time
 import re
 import asyncore
-import glob
 import subprocess
 
 try:
@@ -77,6 +76,12 @@
     pass  # Will fail on Python 2.4 which has reduce() builtin anyway.
 
 try:
+    from glob import iglob as glob
+except ImportError:
+    # Python 2.4 does not have glob.iglob().
+    from glob import glob as glob
+
+try:
     import ctypes
     import ctypes.util
 except ImportError:
@@ -90,7 +95,7 @@
 
 __author__ = "[email protected] (Sebastien Martini)"
 
-__version__ = "0.9.4"
+__version__ = "0.9.5"
 
 __metaclass__ = type  # Use new-style classes by default
 
@@ -197,9 +202,14 @@
 
     def init(self):
         assert ctypes
+
+        try_libc_name = 'c'
+        if sys.platform.startswith('freebsd'):
+            try_libc_name = 'inotify'
+
         libc_name = None
         try:
-            libc_name = ctypes.util.find_library('c')
+            libc_name = ctypes.util.find_library(try_libc_name)
         except (OSError, IOError):
             pass  # Will attemp to load it with None anyway.
 
@@ -223,7 +233,7 @@
 
         self._libc.inotify_init.argtypes = []
         self._libc.inotify_init.restype = ctypes.c_int
-        self._libc.inotify_add_watch.argtypes = [ctypes.c_int, 
ctypes.c_char_p, 
+        self._libc.inotify_add_watch.argtypes = [ctypes.c_int, ctypes.c_char_p,
                                                  ctypes.c_uint32]
         self._libc.inotify_add_watch.restype = ctypes.c_int
         self._libc.inotify_rm_watch.argtypes = [ctypes.c_int, ctypes.c_int]
@@ -305,22 +315,26 @@
 
     def get_val(self):
         """
-        Gets attribute's value.
+        Gets attribute's value. Raises OSError if the operation failed.
 
         @return: stored value.
         @rtype: int
         """
         oldv = ctypes.c_int(0)
         size = ctypes.c_int(ctypes.sizeof(oldv))
-        self._inotify_wrapper._sysctl(self._attr, 3,
-                                      ctypes.c_voidp(ctypes.addressof(oldv)),
-                                      ctypes.addressof(size),
-                                      None, 0)
+        sysctl = self._inotify_wrapper._sysctl
+        res = sysctl(self._attr, 3,
+                     ctypes.c_voidp(ctypes.addressof(oldv)),
+                     ctypes.addressof(size),
+                     None, 0)
+        if res == -1:
+            raise OSError(self._inotify_wrapper.get_errno(),
+                          self._inotify_wrapper.str_errno())
         return oldv.value
 
     def set_val(self, nval):
         """
-        Sets new attribute's value.
+        Sets new attribute's value. Raises OSError if the operation failed.
 
         @param nval: replaces current value by nval.
         @type nval: int
@@ -329,11 +343,15 @@
         sizeo = ctypes.c_int(ctypes.sizeof(oldv))
         newv = ctypes.c_int(nval)
         sizen = ctypes.c_int(ctypes.sizeof(newv))
-        self._inotify_wrapper._sysctl(self._attr, 3,
-                                      ctypes.c_voidp(ctypes.addressof(oldv)),
-                                      ctypes.addressof(sizeo),
-                                      ctypes.c_voidp(ctypes.addressof(newv)),
-                                      ctypes.addressof(sizen))
+        sysctl = self._inotify_wrapper._sysctl
+        res = sysctl(self._attr, 3,
+                     ctypes.c_voidp(ctypes.addressof(oldv)),
+                     ctypes.addressof(sizeo),
+                     ctypes.c_voidp(ctypes.addressof(newv)),
+                     sizen)
+        if res == -1:
+            raise OSError(self._inotify_wrapper.get_errno(),
+                          self._inotify_wrapper.str_errno())
 
     value = property(get_val, set_val)
 
@@ -730,23 +748,28 @@
                 # Since the directory d2 is new, then everything inside it must
                 # also be new.
                 created_dir_wd = addw_ret.get(created_dir)
-                if (created_dir_wd is not None) and (created_dir_wd > 0):
-                    for name in os.listdir(created_dir):
-                        inner = os.path.join(created_dir, name)
-                        if self._watch_manager.get_wd(inner) is not None:
-                            continue
-                        # Generate (simulate) creation events for sub-
-                        # directories and files.
-                        if os.path.isfile(inner):
-                            # symlinks are handled as files.
-                            flags = IN_CREATE
-                        elif os.path.isdir(inner):
-                            flags = IN_CREATE | IN_ISDIR
-                        else:
-                            # This path should not be taken.
-                            continue
-                        rawevent = _RawEvent(created_dir_wd, flags, 0, name)
-                        self._notifier.append_event(rawevent)
+                if ((created_dir_wd is not None) and (created_dir_wd > 0) and
+                    os.path.isdir(created_dir)):
+                    try:
+                        for name in os.listdir(created_dir):
+                            inner = os.path.join(created_dir, name)
+                            if self._watch_manager.get_wd(inner) is not None:
+                                continue
+                            # Generate (simulate) creation events for sub-
+                            # directories and files.
+                            if os.path.isfile(inner):
+                                # symlinks are handled as files.
+                                flags = IN_CREATE
+                            elif os.path.isdir(inner):
+                                flags = IN_CREATE | IN_ISDIR
+                            else:
+                                # This path should not be taken.
+                                continue
+                            rawevent = _RawEvent(created_dir_wd, flags, 0, 
name)
+                            self._notifier.append_event(rawevent)
+                    except OSError, err:
+                        msg = "process_IN_CREATE, invalid directory %s: %s"
+                        log.debug(msg % (created_dir, str(err)))
         return self.process_default(raw_event)
 
     def process_IN_MOVED_FROM(self, raw_event):
@@ -1139,7 +1162,7 @@
                           At least with read_freq set you might sleep.
         @type threshold: int
         @param timeout:
-            http://docs.python.org/lib/poll-objects.html#poll-objects
+            https://docs.python.org/3/library/select.html#polling-objects
         @type timeout: int
         """
         # Watch Manager instance
@@ -1279,6 +1302,9 @@
         """
         while self._eventq:
             raw_event = self._eventq.popleft()  # pop next event
+            if self._watch_manager.ignore_events:
+                log.debug("Event ignored: %s" % repr(raw_event))
+                continue
             watch_ = self._watch_manager.get_watch(raw_event.wd)
             if (watch_ is None) and not (raw_event.mask & IN_Q_OVERFLOW):
                 if not (raw_event.mask & IN_IGNORED):
@@ -1355,7 +1381,6 @@
             # Register unlink function
             atexit.register(lambda : os.unlink(pid_file))
 
-
     def _sleep(self, ref_time):
         # Only consider sleeping if read_freq is > 0
         if self._read_freq > 0:
@@ -1365,7 +1390,6 @@
                 log.debug('Now sleeping %d seconds', sleep_amount)
                 time.sleep(sleep_amount)
 
-
     def loop(self, callback=None, daemonize=False, **args):
         """
         Events are read only one time every min(read_freq, timeout)
@@ -1412,7 +1436,6 @@
         # Close internals
         self.stop()
 
-
     def stop(self):
         """
         Close inotify's instance (close its file descriptor).
@@ -1421,6 +1444,7 @@
         """
         self._pollobj.unregister(self._fd)
         os.close(self._fd)
+        self._sys_proc_fun = None
 
 
 class ThreadedNotifier(threading.Thread, Notifier):
@@ -1455,7 +1479,7 @@
                           least with read_freq you might sleep.
         @type threshold: int
         @param timeout:
-           see http://docs.python.org/lib/poll-objects.html#poll-objects
+            https://docs.python.org/3/library/select.html#polling-objects
         @type timeout: int
         """
         # Init threading base class
@@ -1545,28 +1569,32 @@
     Tornado ioloop adapter.
 
     """
-    def __init__(self, watch_manager, ioloop, callback=None, 
-                 default_proc_fun=None, read_freq=0, threshold=0, 
timeout=None, 
+    def __init__(self, watch_manager, ioloop, callback=None,
+                 default_proc_fun=None, read_freq=0, threshold=0, timeout=None,
                  channel_map=None):
         """
-        Note that if later you must call ioloop.close() be sure to let the 
+        Note that if later you must call ioloop.close() be sure to let the
         default parameter to all_fds=False.
 
         See example tornado_notifier.py for an example using this notifier.
 
         @param ioloop: Tornado's IO loop.
         @type ioloop: tornado.ioloop.IOLoop instance.
-        @param callback: Functor called at the end of each call to handle_read 
-                         (IOLoop's read handler). Expects to receive the 
+        @param callback: Functor called at the end of each call to handle_read
+                         (IOLoop's read handler). Expects to receive the
                          notifier object (self) as single parameter.
         @type callback: callable object or function
         """
-        self.io_loop = ioloop 
+        self.io_loop = ioloop
         self.handle_read_callback = callback
         Notifier.__init__(self, watch_manager, default_proc_fun, read_freq,
                           threshold, timeout)
         ioloop.add_handler(self._fd, self.handle_read, ioloop.READ)
 
+    def stop(self):
+        self.io_loop.remove_handler(self._fd)
+        Notifier.stop(self)
+
     def handle_read(self, *args, **kwargs):
         """
         See comment in AsyncNotifier.
@@ -1578,6 +1606,43 @@
             self.handle_read_callback(self)
 
 
+class AsyncioNotifier(Notifier):
+    """
+
+    asyncio/trollius event loop adapter.
+
+    """
+    def __init__(self, watch_manager, loop, callback=None,
+                 default_proc_fun=None, read_freq=0, threshold=0, 
timeout=None):
+        """
+
+        See examples/asyncio_notifier.py for an example usage.
+
+        @param loop: asyncio or trollius event loop instance.
+        @type loop: asyncio.BaseEventLoop or trollius.BaseEventLoop instance.
+        @param callback: Functor called at the end of each call to handle_read.
+                         Expects to receive the notifier object (self) as
+                         single parameter.
+        @type callback: callable object or function
+
+        """
+        self.loop = loop
+        self.handle_read_callback = callback
+        Notifier.__init__(self, watch_manager, default_proc_fun, read_freq,
+                          threshold, timeout)
+        loop.add_reader(self._fd, self.handle_read)
+
+    def stop(self):
+        self.loop.remove_reader(self._fd)
+        Notifier.stop(self)
+
+    def handle_read(self, *args, **kwargs):
+        self.read_events()
+        self.process_events()
+        if self.handle_read_callback is not None:
+            self.handle_read_callback(self)
+
+
 class Watch:
     """
     Represent a watch, i.e. a file or directory being watched.
@@ -1639,11 +1704,11 @@
     def __init__(self, arg_lst):
         """
         Examples:
-          ef1 = ExcludeFilter(["^/etc/rc.*", "^/etc/hostname"])
+          ef1 = ExcludeFilter(["/etc/rc.*", "/etc/hostname"])
           ef2 = ExcludeFilter("/my/path/exclude.lst")
           Where exclude.lst contains:
-          ^/etc/rc.*
-          ^/etc/hostname
+          /etc/rc.*
+          /etc/hostname
 
         Note: it is not possible to exclude a file if its encapsulating
               directory is itself watched. See this issue for more details
@@ -1734,6 +1799,7 @@
                                filter for every call to add_watch.
         @type exclude_filter: callable object
         """
+        self._ignore_events = False
         self._exclude_filter = exclude_filter
         self._wmd = {}  # watch dict key: watch descriptor, value: watch
 
@@ -1830,7 +1896,7 @@
 
     def __glob(self, path, do_glob):
         if do_glob:
-            return glob.iglob(path)
+            return glob(path)
         else:
             return [path]
 
@@ -2166,6 +2232,16 @@
                               auto_add=False, do_glob=False,
                               exclude_filter=lambda path: False)
 
+    def get_ignore_events(self):
+        return self._ignore_events
+
+    def set_ignore_events(self, nval):
+        self._ignore_events = nval
+
+    ignore_events = property(get_ignore_events, set_ignore_events,
+                             "Make watch manager ignoring new events.")
+
+
 
 class RawOutputFormat:
     """
@@ -2253,6 +2329,9 @@
     parser.add_option("-a", "--auto_add", action="store_true",
                       dest="auto_add",
                       help="Automatically add watches on new directories")
+    parser.add_option("-g", "--glob", action="store_true",
+                      dest="glob",
+                      help="Treat paths as globs")
     parser.add_option("-e", "--events-list", metavar="EVENT[,...]",
                       dest="events_list",
                       help=("A comma-separated list of events to watch for - "
@@ -2328,7 +2407,7 @@
 
     log.debug('Start monitoring %s, (press c^c to halt pyinotify)' % path)
 
-    wm.add_watch(path, mask, rec=options.recursive, auto_add=options.auto_add)
+    wm.add_watch(path, mask, rec=options.recursive, auto_add=options.auto_add, 
do_glob=options.glob)
     # Loop forever (until sigint signal get caught)
     notifier.loop(callback=cb_fun)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyinotify-0.9.4/python3/examples/asyncio_notifier.py 
new/pyinotify-0.9.5/python3/examples/asyncio_notifier.py
--- old/pyinotify-0.9.4/python3/examples/asyncio_notifier.py    1970-01-01 
01:00:00.000000000 +0100
+++ new/pyinotify-0.9.5/python3/examples/asyncio_notifier.py    2014-12-22 
16:53:32.000000000 +0100
@@ -0,0 +1,20 @@
+import pyinotify
+import asyncio
+
+
+def handle_read_callback(notifier):
+    """
+    Just stop receiving IO read events after the first
+    iteration (unrealistic example).
+    """
+    print('handle_read callback')
+    notifier.loop.stop()
+
+
+wm = pyinotify.WatchManager()
+loop = asyncio.get_event_loop()
+notifier = pyinotify.AsyncioNotifier(wm, loop,
+                                     callback=handle_read_callback)
+wm.add_watch('/tmp', pyinotify.ALL_EVENTS)
+loop.run_forever()
+notifier.stop()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyinotify-0.9.4/python3/pyinotify.py 
new/pyinotify-0.9.5/python3/pyinotify.py
--- old/pyinotify-0.9.4/python3/pyinotify.py    2012-11-15 19:39:22.000000000 
+0100
+++ new/pyinotify-0.9.5/python3/pyinotify.py    2015-01-09 22:13:32.000000000 
+0100
@@ -1,7 +1,7 @@
 #!/usr/bin/env python
 
 # pyinotify.py - python interface to inotify
-# Copyright (c) 2005-2011 Sebastien Martini <[email protected]>
+# Copyright (c) 2005-2015 Sebastien Martini <[email protected]>
 #
 # Permission is hereby granted, free of charge, to any person obtaining a copy
 # of this software and associated documentation files (the "Software"), to deal
@@ -92,7 +92,7 @@
 
 __author__ = "[email protected] (Sebastien Martini)"
 
-__version__ = "0.9.4"
+__version__ = "0.9.5"
 
 
 # Compatibity mode: set to True to improve compatibility with
@@ -200,9 +200,14 @@
 
     def init(self):
         assert ctypes
+
+        try_libc_name = 'c'
+        if sys.platform.startswith('freebsd'):
+            try_libc_name = 'inotify'
+
         libc_name = None
         try:
-            libc_name = ctypes.util.find_library('c')
+            libc_name = ctypes.util.find_library(try_libc_name)
         except (OSError, IOError):
             pass  # Will attemp to load it with None anyway.
 
@@ -300,22 +305,26 @@
 
     def get_val(self):
         """
-        Gets attribute's value.
+        Gets attribute's value. Raises OSError if the operation failed.
 
         @return: stored value.
         @rtype: int
         """
         oldv = ctypes.c_int(0)
         size = ctypes.c_int(ctypes.sizeof(oldv))
-        self._inotify_wrapper._sysctl(self._attr, 3,
-                                      ctypes.c_voidp(ctypes.addressof(oldv)),
-                                      ctypes.addressof(size),
-                                      None, 0)
+        sysctl = self._inotify_wrapper._sysctl
+        res = sysctl(self._attr, 3,
+                     ctypes.c_voidp(ctypes.addressof(oldv)),
+                     ctypes.addressof(size),
+                     None, 0)
+        if res == -1:
+            raise OSError(self._inotify_wrapper.get_errno(),
+                          self._inotify_wrapper.str_errno())
         return oldv.value
 
     def set_val(self, nval):
         """
-        Sets new attribute's value.
+        Sets new attribute's value. Raises OSError if the operation failed.
 
         @param nval: replaces current value by nval.
         @type nval: int
@@ -324,11 +333,15 @@
         sizeo = ctypes.c_int(ctypes.sizeof(oldv))
         newv = ctypes.c_int(nval)
         sizen = ctypes.c_int(ctypes.sizeof(newv))
-        self._inotify_wrapper._sysctl(self._attr, 3,
-                                      ctypes.c_voidp(ctypes.addressof(oldv)),
-                                      ctypes.addressof(sizeo),
-                                      ctypes.c_voidp(ctypes.addressof(newv)),
-                                      ctypes.addressof(sizen))
+        sysctl = self._inotify_wrapper._sysctl
+        res = sysctl(self._attr, 3,
+                     ctypes.c_voidp(ctypes.addressof(oldv)),
+                     ctypes.addressof(sizeo),
+                     ctypes.c_voidp(ctypes.addressof(newv)),
+                     sizen)
+        if res == -1:
+            raise OSError(self._inotify_wrapper.get_errno(),
+                          self._inotify_wrapper.str_errno())
 
     value = property(get_val, set_val)
 
@@ -725,23 +738,28 @@
                 # Since the directory d2 is new, then everything inside it must
                 # also be new.
                 created_dir_wd = addw_ret.get(created_dir)
-                if (created_dir_wd is not None) and (created_dir_wd > 0):
-                    for name in os.listdir(created_dir):
-                        inner = os.path.join(created_dir, name)
-                        if self._watch_manager.get_wd(inner) is not None:
-                            continue
-                        # Generate (simulate) creation events for sub-
-                        # directories and files.
-                        if os.path.isfile(inner):
-                            # symlinks are handled as files.
-                            flags = IN_CREATE
-                        elif os.path.isdir(inner):
-                            flags = IN_CREATE | IN_ISDIR
-                        else:
-                            # This path should not be taken.
-                            continue
-                        rawevent = _RawEvent(created_dir_wd, flags, 0, name)
-                        self._notifier.append_event(rawevent)
+                if ((created_dir_wd is not None) and (created_dir_wd > 0) and
+                    os.path.isdir(created_dir)):
+                    try:
+                        for name in os.listdir(created_dir):
+                            inner = os.path.join(created_dir, name)
+                            if self._watch_manager.get_wd(inner) is not None:
+                                continue
+                            # Generate (simulate) creation events for sub-
+                            # directories and files.
+                            if os.path.isfile(inner):
+                                # symlinks are handled as files.
+                                flags = IN_CREATE
+                            elif os.path.isdir(inner):
+                                flags = IN_CREATE | IN_ISDIR
+                            else:
+                                # This path should not be taken.
+                                continue
+                            rawevent = _RawEvent(created_dir_wd, flags, 0, 
name)
+                            self._notifier.append_event(rawevent)
+                    except OSError as err:
+                        msg = "process_IN_CREATE, invalid directory: %s"
+                        log.debug(msg % str(err))
         return self.process_default(raw_event)
 
     def process_IN_MOVED_FROM(self, raw_event):
@@ -1276,6 +1294,9 @@
         """
         while self._eventq:
             raw_event = self._eventq.popleft()  # pop next event
+            if self._watch_manager.ignore_events:
+                log.debug("Event ignored: %s" % repr(raw_event))
+                continue
             watch_ = self._watch_manager.get_watch(raw_event.wd)
             if (watch_ is None) and not (raw_event.mask & IN_Q_OVERFLOW):
                 if not (raw_event.mask & IN_IGNORED):
@@ -1350,7 +1371,6 @@
             # Register unlink function
             atexit.register(lambda : os.unlink(pid_file))
 
-
     def _sleep(self, ref_time):
         # Only consider sleeping if read_freq is > 0
         if self._read_freq > 0:
@@ -1360,7 +1380,6 @@
                 log.debug('Now sleeping %d seconds', sleep_amount)
                 time.sleep(sleep_amount)
 
-
     def loop(self, callback=None, daemonize=False, **args):
         """
         Events are read only one time every min(read_freq, timeout)
@@ -1407,7 +1426,6 @@
         # Close internals
         self.stop()
 
-
     def stop(self):
         """
         Close inotify's instance (close its file descriptor).
@@ -1416,6 +1434,7 @@
         """
         self._pollobj.unregister(self._fd)
         os.close(self._fd)
+        self._sys_proc_fun = None
 
 
 class ThreadedNotifier(threading.Thread, Notifier):
@@ -1562,6 +1581,10 @@
                           threshold, timeout)
         ioloop.add_handler(self._fd, self.handle_read, ioloop.READ)
 
+    def stop(self):
+        self.io_loop.remove_handler(self._fd)
+        Notifier.stop(self)
+
     def handle_read(self, *args, **kwargs):
         """
         See comment in AsyncNotifier.
@@ -1573,6 +1596,43 @@
             self.handle_read_callback(self)
 
 
+class AsyncioNotifier(Notifier):
+    """
+
+    asyncio/trollius event loop adapter.
+
+    """
+    def __init__(self, watch_manager, loop, callback=None,
+                 default_proc_fun=None, read_freq=0, threshold=0, 
timeout=None):
+        """
+
+        See examples/asyncio_notifier.py for an example usage.
+
+        @param loop: asyncio or trollius event loop instance.
+        @type loop: asyncio.BaseEventLoop or trollius.BaseEventLoop instance.
+        @param callback: Functor called at the end of each call to handle_read.
+                         Expects to receive the notifier object (self) as
+                         single parameter.
+        @type callback: callable object or function
+
+        """
+        self.loop = loop
+        self.handle_read_callback = callback
+        Notifier.__init__(self, watch_manager, default_proc_fun, read_freq,
+                          threshold, timeout)
+        loop.add_reader(self._fd, self.handle_read)
+
+    def stop(self):
+        self.loop.remove_reader(self._fd)
+        Notifier.stop(self)
+
+    def handle_read(self, *args, **kwargs):
+        self.read_events()
+        self.process_events()
+        if self.handle_read_callback is not None:
+            self.handle_read_callback(self)
+
+
 class Watch:
     """
     Represent a watch, i.e. a file or directory being watched.
@@ -1633,11 +1693,11 @@
     def __init__(self, arg_lst):
         """
         Examples:
-          ef1 = ExcludeFilter(["^/etc/rc.*", "^/etc/hostname"])
+          ef1 = ExcludeFilter(["/etc/rc.*", "/etc/hostname"])
           ef2 = ExcludeFilter("/my/path/exclude.lst")
           Where exclude.lst contains:
-          ^/etc/rc.*
-          ^/etc/hostname
+          /etc/rc.*
+          /etc/hostname
 
         Note: it is not possible to exclude a file if its encapsulating
               directory is itself watched. See this issue for more details
@@ -1724,6 +1784,7 @@
                                filter for every call to add_watch.
         @type exclude_filter: callable object
         """
+        self._ignore_events = False
         self._exclude_filter = exclude_filter
         self._wmd = {}  # watch dict key: watch descriptor, value: watch
 
@@ -2152,6 +2213,15 @@
                               auto_add=False, do_glob=False,
                               exclude_filter=lambda path: False)
 
+    def get_ignore_events(self):
+        return self._ignore_events
+
+    def set_ignore_events(self, nval):
+        self._ignore_events = nval
+
+    ignore_events = property(get_ignore_events, set_ignore_events,
+                             "Make watch manager ignoring new events.")
+
 
 class RawOutputFormat:
     """
@@ -2239,6 +2309,9 @@
     parser.add_option("-a", "--auto_add", action="store_true",
                       dest="auto_add",
                       help="Automatically add watches on new directories")
+    parser.add_option("-g", "--glob", action="store_true",
+                      dest="glob",
+                      help="Treat paths as globs")
     parser.add_option("-e", "--events-list", metavar="EVENT[,...]",
                       dest="events_list",
                       help=("A comma-separated list of events to watch for - "
@@ -2314,7 +2387,7 @@
 
     log.debug('Start monitoring %s, (press c^c to halt pyinotify)' % path)
 
-    wm.add_watch(path, mask, rec=options.recursive, auto_add=options.auto_add)
+    wm.add_watch(path, mask, rec=options.recursive, auto_add=options.auto_add, 
do_glob=options.glob)
     # Loop forever (until sigint signal get caught)
     notifier.loop(callback=cb_fun)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyinotify-0.9.4/setup.cfg 
new/pyinotify-0.9.5/setup.cfg
--- old/pyinotify-0.9.4/setup.cfg       1970-01-01 01:00:00.000000000 +0100
+++ new/pyinotify-0.9.5/setup.cfg       2015-01-09 22:49:28.000000000 +0100
@@ -0,0 +1,5 @@
+[egg_info]
+tag_build = 
+tag_date = 0
+tag_svn_revision = 0
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyinotify-0.9.4/setup.py new/pyinotify-0.9.5/setup.py
--- old/pyinotify-0.9.4/setup.py        2012-11-15 19:39:22.000000000 +0100
+++ new/pyinotify-0.9.5/setup.py        2015-01-09 22:11:57.000000000 +0100
@@ -25,7 +25,7 @@
     sys.exit(1)
 
 # check linux platform
-if not platform.startswith('linux'):
+if not platform.startswith('linux') and not platform.startswith('freebsd'):
     sys.stderr.write("inotify is not available on %s\n" % platform)
     sys.exit(1)
 
@@ -46,6 +46,10 @@
     'Programming Language :: Python :: 3.0',
     'Programming Language :: Python :: 3.1',
     'Programming Language :: Python :: 3.2',
+    'Programming Language :: Python :: 3.3',
+    'Programming Language :: Python :: 3.4',
+    'Programming Language :: Python :: Implementation :: CPython',
+    'Programming Language :: Python :: Implementation :: PyPy',
     'Topic :: Software Development :: Libraries :: Python Modules',
     'Topic :: System :: Filesystems',
     'Topic :: System :: Monitoring',
@@ -66,9 +70,13 @@
     except:
         return True
 
+    try_libc_name = 'c'
+    if platform.startswith('freebsd'):
+        try_libc_name = 'inotify'
+
     libc_name = None
     try:
-        libc_name = ctypes.util.find_library('c')
+        libc_name = ctypes.util.find_library(try_libc_name)
     except:
         pass  # Will attemp to load it with None anyway.
 
@@ -89,13 +97,13 @@
     # sources for ext module
     ext_mod_src = ['common/inotify_syscalls.c']
     # dst for ext module
-    ext_mod.append(distutils.extension.Extension('inotify_syscalls', 
+    ext_mod.append(distutils.extension.Extension('inotify_syscalls',
                                                  ext_mod_src))
 
 
 setup(
     name='pyinotify',
-    version='0.9.4',
+    version='0.9.5',
     description='Linux filesystem events monitoring',
     author='Sebastien Martini',
     author_email='[email protected]',

-- 
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to