[mac] Fix callback exceptions when the watcher is deleted but still receiving events (#786)

The watcher might be cleared on thread stop but the C callback would still send events,
ending in unhandled exceptions later:

    AttributeError: 'NoneType' object has no attribute 'is_recursive'
      File "watchdog/observers/fsevents.py", line 299, in callback
        emitter.queue_events(emitter.timeout, events)
      File "watchdog/observers/fsevents.py", line 261, in queue_events
        self._queue_created_event(event, src_path, src_dirname)
      File "watchdog/observers/fsevents.py", line 124, in _queue_created_event
        self.queue_event(DirModifiedEvent(dirname))
      File "watchdog/observers/fsevents.py", line 97, in queue_event
        if self._watch.is_recursive :

Or even:

    AttributeError: 'NoneType' object has no attribute 'path'
      File "watchdog/observers/fsevents.py", line 299, in callback
        emitter.queue_events(emitter.timeout, events)
      File "watchdog/observers/fsevents.py", line 174, in queue_events
        src_path = self._encode_path(event.path)
      File "watchdog/observers/fsevents.py", line 323, in _encode_path
        if isinstance(self.watch.path, bytes):

The C extension wasn't great at dealing with some of the edge cases when watches are removed.
This manifested itself in a couple of different errors. Some of them were worked around in Python
land, most notably with checks for `self._watch` and setting it to `None` when it was removed.
This masked an issue where we assumed that a watch was always found in the internal lookup
dictionary when it was removed. With this issue fixed we can remove those checks, which is
also done here.

Co-authored-by: Romain Grasland <rgrasland@nuxeo.com>
Co-authored-by: Thomas <thomas@ccpgames.com>
4 files changed