diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index cc9df6f..53ddd77 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -3,7 +3,7 @@ default_language_version: repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.1.0 + rev: v4.3.0 hooks: - id: check-added-large-files - id: check-case-conflict @@ -14,24 +14,24 @@ repos: - id: end-of-file-fixer - id: trailing-whitespace - repo: https://github.com/pre-commit/mirrors-prettier - rev: v2.6.0 + rev: v3.0.0-alpha.0 hooks: - id: prettier types_or: - css - repo: https://github.com/standard/standard - rev: v17.0.0-2 + rev: v17.0.0 hooks: - id: standard args: - --env=browser - repo: https://github.com/asottile/pyupgrade - rev: v2.31.1 + rev: v2.37.3 hooks: - id: pyupgrade args: [--py37-plus] - repo: https://github.com/psf/black - rev: 22.1.0 + rev: 22.8.0 hooks: - id: black - repo: https://github.com/asottile/blacken-docs @@ -45,7 +45,7 @@ repos: hooks: - id: isort - repo: https://github.com/PyCQA/flake8 - rev: 4.0.1 + rev: 5.0.4 hooks: - id: flake8 additional_dependencies: @@ -59,6 +59,6 @@ repos: - id: check-manifest args: [--no-build-isolation] - repo: https://github.com/pre-commit/mirrors-mypy - rev: v0.941 + rev: v0.971 hooks: - id: mypy diff --git a/src/django_watchfiles/__init__.py b/src/django_watchfiles/__init__.py index 6093061..b10d7d4 100644 --- a/src/django_watchfiles/__init__.py +++ b/src/django_watchfiles/__init__.py @@ -1,13 +1,22 @@ from __future__ import annotations +import logging +from collections.abc import Callable, Generator from pathlib import Path -from typing import Generator +from typing import Any import watchfiles +from django.conf import settings from django.utils import autoreload +from django.utils.autoreload import run_with_reloader +from django.utils.module_loading import import_string class WatchfilesReloader(autoreload.BaseReloader): + def __init__(self, watchfiles_settings: dict[str, Any]) -> None: + super().__init__() + self.watchfiles_settings = watchfiles_settings + def watched_roots(self, watched_files: list[Path]) -> frozenset[Path]: extra_directories = self.directory_globs.keys() watched_file_dirs = {f.parent for f in watched_files} @@ -17,15 +26,31 @@ def watched_roots(self, watched_files: list[Path]) -> frozenset[Path]: def tick(self) -> Generator[None, None, None]: watched_files = list(self.watched_files(include_globs=False)) roots = autoreload.common_roots(self.watched_roots(watched_files)) - watcher = watchfiles.watch(*roots, debug=True) + watcher = watchfiles.watch(*roots, **self.watchfiles_settings) for file_changes in watcher: for _change, path in file_changes: self.notify_file_changed(Path(path)) yield -def replaced_get_reloader() -> autoreload.BaseReloader: - return WatchfilesReloader() +def replaced_run_with_reloader( + main_func: Callable[..., Any], *args: Any, **kwargs: Any +) -> None: + watchfiles_settings = getattr(settings, "WATCHFILES", {}) + if "watch_filter" in watchfiles_settings: + watchfiles_settings["watch_filter"] = import_string( + watchfiles_settings["watch_filter"] + )() + if watchfiles_settings.get("debug"): + log_level = logging.DEBUG + else: + log_level = 40 - 10 * kwargs["verbosity"] + + watchfiles_settings["debug"] = log_level == logging.DEBUG + logging.getLogger("watchfiles").setLevel(log_level) + + autoreload.get_reloader = lambda: WatchfilesReloader(watchfiles_settings) + return run_with_reloader(main_func, *args, **kwargs) -autoreload.get_reloader = replaced_get_reloader +autoreload.run_with_reloader = replaced_run_with_reloader