Sorry the patch in the original bug report was incorrect. I've attached the right one
--- /usr/share/pyshared/gamin.py 2012-07-26 03:57:19.000000000 +0100 +++ gamin.py 2014-01-30 10:25:10.223748107 +0000 @@ -36,7 +36,7 @@ def GaminErrmsg(err = None): if err == None: - err = _gamin.Errno() + err = _gamin.Errno() if err == GAM_ARG: msg = "bad argument error" elif err == GAM_FILE: @@ -58,12 +58,12 @@ class GaminException(Exception): def __init__(self, value): Exception.__init__(self) - self.value = value - self.errno = GaminErrno() + self.value = value + self.errno = GaminErrno() def __str__(self): str = GaminErrmsg(self.errno) - if str != "": + if str != "": return repr(self.value) + ': ' + str return repr(self.value) @@ -76,161 +76,161 @@ FAM API events.""" class WatchObject: - def __init__ (self, monitor, mon_no, path, dir, callback, data=None): - self.monitor = monitor - self.callback = callback - self.data = data - self.path = path - self.__mon_no = mon_no - if dir == 1: - ret = _gamin.MonitorDirectory(self.__mon_no, path, self); - if ret < 0: - raise(GaminException("Failed to monitor directory %s" % - (path))) - elif dir == 0: - ret = _gamin.MonitorFile(self.__mon_no, path, self); - if ret < 0: - raise(GaminException("Failed to monitor file %s" % - (path))) - elif dir == -1: - ret = _gamin.MonitorDebug(self.__mon_no, path, self); - if ret < 0: - raise(GaminException("Failed to debug %s" % - (path))) - self.__req_no = ret - - def _internal_callback(self, path, event): - # it is very important here to catch all exception which may - # arise in the client callback code. - try: - if self.data != None: - self.callback (path, event, self.data) - else: - self.callback (path, event) - except: - import traceback - traceback.print_exc() - - if event == GAMAcknowledge: - try: - self.monitor.cancelled.remove(self) - except: - print "gamin failed to remove from cancelled" - pass - - def cancel(self): - ret = _gamin.MonitorCancel(self.__mon_no, self.__req_no); - if ret < 0: - raise(GaminException("Failed to stop monitor on %s" % - (self.path))) - try: - self.monitor.cancelled.append(self) - except: - print "gamin cancel() failed to add to cancelled" + def __init__ (self, monitor, mon_no, path, dir, callback, data=None): + self.monitor = monitor + self.callback = callback + self.data = data + self.path = path + self.__mon_no = mon_no + if dir == 1: + ret = _gamin.MonitorDirectory(self.__mon_no, path, self); + if ret < 0: + raise(GaminException("Failed to monitor directory %s" % + (path))) + elif dir == 0: + ret = _gamin.MonitorFile(self.__mon_no, path, self); + if ret < 0: + raise(GaminException("Failed to monitor file %s" % + (path))) + elif dir == -1: + ret = _gamin.MonitorDebug(self.__mon_no, path, self); + if ret < 0: + raise(GaminException("Failed to debug %s" % + (path))) + self.__req_no = ret + + def _internal_callback(self, path, event): + # it is very important here to catch all exception which may + # arise in the client callback code. + try: + if self.data != None: + self.callback (path, event, self.data) + else: + self.callback (path, event) + except: + import traceback + traceback.print_exc() + + if event == GAMAcknowledge: + try: + self.monitor.cancelled.remove(self) + except: + print "gamin failed to remove from cancelled" + pass + + def cancel(self): + ret = _gamin.MonitorCancel(self.__mon_no, self.__req_no); + if ret < 0: + raise(GaminException("Failed to stop monitor on %s" % + (self.path))) + try: + self.monitor.cancelled.append(self) + except: + print "gamin cancel() failed to add to cancelled" def __init__ (self): self.__no = _gamin.MonitorConnect() - if self.__no < 0: - raise(GaminException("Failed to connect to gam_server")) - self.objects = {} - self.__fd = _gamin.GetFd(self.__no) - if self.__fd < 0: - _gamin.MonitorClose(self.__no) - raise(GaminException("Failed to get file descriptor")) - self.cancelled = [] + if self.__no < 0: + raise(GaminException("Failed to connect to gam_server")) + self.objects = {} + self.__fd = _gamin.GetFd(self.__no) + if self.__fd < 0: + _gamin.MonitorClose(self.__no) + raise(GaminException("Failed to get file descriptor")) + self.cancelled = [] def __del__ (self): self.disconnect() def __raise_disconnected(): - raise(GaminException("Already disconnected")) + raise(GaminException("Already disconnected")) def _debug_object(self, value, callback, data = None): if has_debug_api == 0: - return; + return; if (self.__no < 0): - self.__raise_disconnected(); + self.__raise_disconnected(); obj = self.WatchObject(self, self.__no, value, -1, callback, data) - # persistency need to be insured - self.objects["debug"] = obj - return obj + # persistency need to be insured + self.objects["debug"] = obj + return obj def disconnect(self): if (self.__no >= 0): - _gamin.MonitorClose(self.__no) - self.__no = -1; + _gamin.MonitorClose(self.__no) + self.__no = -1; def watch_directory(self, directory, callback, data = None): if (self.__no < 0): - self.__raise_disconnected(); + self.__raise_disconnected(); directory = os.path.abspath(directory) obj = self.WatchObject(self, self.__no, directory, 1, callback, data) if self.objects.has_key(directory): - self.objects[directory].append(obj) - else: - self.objects[directory] = [obj] - return obj + self.objects[directory].append(obj) + else: + self.objects[directory] = [obj] + return obj def watch_file(self, file, callback, data = None): if (self.__no < 0): - self.__raise_disconnected(); + self.__raise_disconnected(); file = os.path.abspath(file) obj = self.WatchObject(self, self.__no, file, 0, callback, data) if self.objects.has_key(file): - self.objects[file].append(obj) - else: - self.objects[file] = [obj] - return obj + self.objects[file].append(obj) + else: + self.objects[file] = [obj] + return obj def no_exists(self): if (self.__no < 0): - return - ret = _gamin.MonitorNoExists(self.__no) - return ret + return + ret = _gamin.MonitorNoExists(self.__no) + return ret def stop_watch(self, path): if (self.__no < 0): - return + return path = os.path.abspath(path) - try: - list = self.objects[path] - except: - raise(GaminException("Resource %s is not monitored" % (path))) - for obj in list: - obj.cancel() - self.objects[path] = [] - + try: + list = self.objects[path] + except: + raise(GaminException("Resource %s is not monitored" % (path))) + for obj in list: + obj.cancel() + self.objects[path] = [] + def get_fd(self): if (self.__no < 0): - self.__raise_disconnected(); + self.__raise_disconnected(); return self.__fd def event_pending(self): if (self.__no < 0): - self.__raise_disconnected(); + self.__raise_disconnected(); ret = _gamin.EventPending(self.__no); - if ret < 0: - raise(GaminException("Failed to check pending events")) - return ret + if ret < 0: + raise(GaminException("Failed to check pending events")) + return ret def handle_one_event(self): if (self.__no < 0): - self.__raise_disconnected(); + self.__raise_disconnected(); ret = _gamin.ProcessOneEvent(self.__no); - if ret < 0: - raise(GaminException("Failed to process one event")) - return ret + if ret < 0: + raise(GaminException("Failed to process one event")) + return ret def handle_events(self): if (self.__no < 0): - self.__raise_disconnected(); + self.__raise_disconnected(); ret = _gamin.ProcessEvents(self.__no); - if ret < 0: - raise(GaminException("Failed to process events")) - return ret + if ret < 0: + raise(GaminException("Failed to process events")) + return ret def run_unit_tests(): def callback(path, event): @@ -245,9 +245,9 @@ print "pending: ", ret if ret > 0: ret = mon.handle_one_event() - print "processed %d event" % (ret) - ret = mon.handle_events() - print "processed %d remaining events" % (ret) + print "processed %d event" % (ret) + ret = mon.handle_events() + print "processed %d remaining events" % (ret) print "stop watching current directory" mon.stop_watch(".") print "disconnecting"