Skip to content

Commit

Permalink
Fix a TypeError when deleting the watched folder on Windows
Browse files Browse the repository at this point in the history
  • Loading branch information
BoboTiG committed Dec 11, 2019
1 parent 7a55f31 commit 56b712b
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 5 deletions.
2 changes: 1 addition & 1 deletion src/watchdog/observers/winapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ def _is_observed_path_deleted(handle, path):
def _generate_observed_path_deleted_event():
# Create synthetic event for notify that observed directory is deleted
path = ctypes.create_unicode_buffer('.')
event = FILE_NOTIFY_INFORMATION(0, FILE_ACTION_DELETED_SELF, len(path), path.value)
event = FILE_NOTIFY_INFORMATION(0, FILE_ACTION_DELETED_SELF, len(path), path.value.encode("utf-8"))
event_size = ctypes.sizeof(event)
buff = ctypes.create_string_buffer(BUFFER_SIZE)
ctypes.memmove(buff, ctypes.addressof(event), event_size)
Expand Down
55 changes: 51 additions & 4 deletions tests/test_observers_winapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
if not platform.is_windows(): # noqa
pytest.skip("Windows only.", allow_module_level=True)

import os
import os.path
from time import sleep

Expand All @@ -36,11 +37,16 @@
from .shell import (
mkdir,
mkdtemp,
mv
mv,
rm
)


temp_dir = mkdtemp()
SLEEP_TIME = 2

# Path with non-ASCII
temp_dir = os.path.join(mkdtemp(), u"Strange \N{SNOWMAN}")
os.makedirs(temp_dir)


def p(*args):
Expand All @@ -65,8 +71,6 @@ def emitter(event_queue):


def test___init__(event_queue, emitter):
SLEEP_TIME = 2

emitter.start()
sleep(SLEEP_TIME)
mkdir(p('fromdir'))
Expand Down Expand Up @@ -98,3 +102,46 @@ def test___init__(event_queue, emitter):
got.add(event)

assert expected == got


def test_root_deleted(event_queue, emitter):
r"""Test the event got when removing the watched folder.
The regression to prevent is:
Exception in thread Thread-1:
Traceback (most recent call last):
File "watchdog\observers\winapi.py", line 333, in read_directory_changes
ctypes.byref(nbytes), None, None)
File "watchdog\observers\winapi.py", line 105, in _errcheck_bool
raise ctypes.WinError()
PermissionError: [WinError 5] Access refused.
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Python37-32\lib\threading.py", line 926, in _bootstrap_inner
self.run()
File "watchdog\observers\api.py", line 145, in run
self.queue_events(self.timeout)
File "watchdog\observers\read_directory_changes.py", line 76, in queue_events
winapi_events = self._read_events()
File "watchdog\observers\read_directory_changes.py", line 73, in _read_events
return read_events(self._handle, self.watch.path, self.watch.is_recursive)
File "watchdog\observers\winapi.py", line 387, in read_events
buf, nbytes = read_directory_changes(handle, path, recursive)
File "watchdog\observers\winapi.py", line 340, in read_directory_changes
return _generate_observed_path_deleted_event()
File "watchdog\observers\winapi.py", line 298, in _generate_observed_path_deleted_event
event = FILE_NOTIFY_INFORMATION(0, FILE_ACTION_DELETED_SELF, len(path), path.value)
TypeError: expected bytes, str found
"""

emitter.start()
sleep(SLEEP_TIME)

# This should not fail
rm(p(), recursive=True)
sleep(SLEEP_TIME)

# The emitter is automatically stopped, with no error
assert not emitter.should_keep_running()

0 comments on commit 56b712b

Please sign in to comment.