From d7ac0f6457826f1186978f1f097c8498ac1519c0 Mon Sep 17 00:00:00 2001 From: Steven Mapes Date: Mon, 28 Oct 2024 22:00:30 +0000 Subject: [PATCH] Ignore non-existent directories (#117) Fixes #12. --------- Co-authored-by: Adam Johnson --- CHANGELOG.rst | 4 ++++ src/django_watchfiles/__init__.py | 4 +++- tests/test_django_watchfiles.py | 8 ++++++++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index b5d1cf2..4ad3e7d 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -11,6 +11,10 @@ Unreleased * Support Python 3.13. +* Fix crashing on non-existent directories, which Django sometimes tries to watch. + + Thanks to baseplate-admin for the report in `Issue #12 `__ and Steven Mapes for the fix in `PR #117 `__. + 0.2.0 (2024-06-19) ------------------ diff --git a/src/django_watchfiles/__init__.py b/src/django_watchfiles/__init__.py index 19b05eb..bc59adb 100644 --- a/src/django_watchfiles/__init__.py +++ b/src/django_watchfiles/__init__.py @@ -80,7 +80,9 @@ def watched_roots(self, watched_files: Iterable[Path]) -> frozenset[Path]: extra_directories = self.directory_globs.keys() watched_file_dirs = {f.parent for f in watched_files} sys_paths = set(autoreload.sys_path_directories()) - return frozenset((*extra_directories, *watched_file_dirs, *sys_paths)) + all_dirs = (*extra_directories, *watched_file_dirs, *sys_paths) + existing_dirs = (p for p in all_dirs if p.exists()) + return frozenset(existing_dirs) def tick(self) -> Generator[None]: self.watched_files_set = set(self.watched_files(include_globs=False)) diff --git a/tests/test_django_watchfiles.py b/tests/test_django_watchfiles.py index 6cfb824..c14e5b6 100644 --- a/tests/test_django_watchfiles.py +++ b/tests/test_django_watchfiles.py @@ -163,6 +163,14 @@ def test_tick(self): result = self.reloader.file_filter(Change.modified, str(test_txt)) assert result is True + def test_tick_non_existent_directory_watched(self): + does_not_exist = self.temp_path / "nope" + self.reloader.watch_dir(does_not_exist, "*.txt") + + iterator = self.reloader.tick() + result = next(iterator) + assert result is None + class ReplacedGetReloaderTests(SimpleTestCase): def test_replaced_get_reloader(self):