diff --git a/django/utils/autoreload.py b/django/utils/autoreload.py index fc330eb87e..f6215d4edf 100644 --- a/django/utils/autoreload.py +++ b/django/utils/autoreload.py @@ -240,8 +240,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 2d69ad44e0..41d0623568 100644 --- a/django/utils/translation/reloader.py +++ b/django/utils/translation/reloader.py @@ -14,8 +14,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 af0950d700..16e3bf07be 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 5de276f035..b673c5e1c0 100644 --- a/tests/utils_tests/test_autoreload.py +++ b/tests/utils_tests/test_autoreload.py @@ -499,6 +499,12 @@ class IntegrationTests: class BaseReloaderTests(ReloaderTests): RELOADER_CLS = autoreload.BaseReloader + 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())