diff --git a/django/utils/autoreload.py b/django/utils/autoreload.py index 3153f3f14d9..aa152343d6b 100644 --- a/django/utils/autoreload.py +++ b/django/utils/autoreload.py @@ -235,8 +235,15 @@ class BaseReloader: def watch_dir(self, path, glob): path = Path(path) - if not path.is_absolute(): - raise ValueError('%s must be absolute.' % path) + try: + path = path.absolute() + except FileNotFoundError: + logger.debug( + 'Unable to watch directory %s as it cannot be resolved.', + path, + exc_info=True, + ) + return logger.debug('Watching dir %s with glob %s.', path, glob) self.directory_globs[path].add(glob) diff --git a/django/utils/translation/reloader.py b/django/utils/translation/reloader.py index 8e2d320208f..4b363f51299 100644 --- a/django/utils/translation/reloader.py +++ b/django/utils/translation/reloader.py @@ -13,8 +13,7 @@ def watch_for_translation_changes(sender, **kwargs): directories.extend(Path(config.path) / 'locale' for config in apps.get_app_configs()) directories.extend(Path(p) for p in settings.LOCALE_PATHS) for path in directories: - absolute_path = path.absolute() - sender.watch_dir(absolute_path, '**/*.mo') + sender.watch_dir(path, '**/*.mo') def translation_file_changed(sender, file_path, **kwargs): diff --git a/docs/releases/2.2.4.txt b/docs/releases/2.2.4.txt index af0950d7005..16e3bf07beb 100644 --- a/docs/releases/2.2.4.txt +++ b/docs/releases/2.2.4.txt @@ -21,3 +21,6 @@ Bugfixes * Fixed a regression in Django 2.2 where auto-reloader crashes if a file path contains nulls characters (``'\x00'``) (:ticket:`30506`). + +* Fixed a regression in Django 2.2 where auto-reloader crashes if a translation + directory cannot be resolved (:ticket:`30647`). diff --git a/tests/utils_tests/test_autoreload.py b/tests/utils_tests/test_autoreload.py index 59eb32ed70d..64c71bfe3f6 100644 --- a/tests/utils_tests/test_autoreload.py +++ b/tests/utils_tests/test_autoreload.py @@ -515,6 +515,12 @@ class BaseReloaderTests(ReloaderTests): watched_files = list(self.reloader.watched_files()) self.assertIn(self.existing_file, watched_files) + def test_watch_dir_with_unresolvable_path(self): + path = Path('unresolvable_directory') + with mock.patch.object(Path, 'absolute', side_effect=FileNotFoundError): + self.reloader.watch_dir(path, '**/*.mo') + self.assertEqual(list(self.reloader.directory_globs), []) + def test_watch_with_glob(self): self.reloader.watch_dir(self.tempdir, '*.py') watched_files = list(self.reloader.watched_files())