@@ -42,10 +42,17 @@ def _watch_stub(*args, **kwargs):
4242 sys .modules .setdefault ("watchfiles" , shim )
4343
4444
45- class PytronFilter (DefaultFilter ):
45+ class PytronFilter :
46+ """
47+ A custom filter for watchfiles that ignores common build/temp dirs.
48+ Only ignores them if they are subdirectories of the project root.
49+ """
50+
4651 def __init__ (self , project_root : Path = None , frontend_dir : Path = None , ** kwargs ):
4752 self .project_root = (project_root or Path .cwd ()).resolve ()
4853 self .frontend_dir = frontend_dir .resolve () if frontend_dir else None
54+
55+ # Directory names to ignore ONLY if they are within the project
4956 self .ignore_dirs = {
5057 ".git" ,
5158 "__pycache__" ,
@@ -64,25 +71,9 @@ def __init__(self, project_root: Path = None, frontend_dir: Path = None, **kwarg
6471 "temp" ,
6572 "tmp" ,
6673 }
67- super ().__init__ (** kwargs )
68-
69- def __call__ (self , change , path ):
70- path_obj = Path (path ).resolve ()
71-
72- # 0. Get parts relative to project root to avoid ignoring system dirs like /tmp
73- try :
74- rel_parts = path_obj .relative_to (self .project_root ).parts
7574
76- # 1. Ignore common heavy or build directories ONLY if they are inside project root
77- if any (part in self .ignore_dirs for part in rel_parts ):
78- return False
79- except ValueError :
80- # If outside project root (e.g. system files or temp tests),
81- # don't apply project-specific ignore_dirs
82- pass
83-
84- # 1.5 Ignore database, log, and temp files that constantly change
85- if path_obj .suffix .lower () in {
75+ # Standard file extensions/patterns to always ignore
76+ self .ignore_entity_patterns = {
8677 ".db" ,
8778 ".sqlite" ,
8879 ".sqlite3" ,
@@ -93,25 +84,43 @@ def __call__(self, change, path):
9384 ".tmp" ,
9485 ".swp" ,
9586 ".pyc" ,
96- }:
87+ ".pyo" ,
88+ ".pyd" ,
89+ ".exe" ,
90+ ".dll" ,
91+ ".so" ,
92+ ".dylib" ,
93+ }
94+
95+ def __call__ (self , change , path ):
96+ path_obj = Path (path ).resolve ()
97+
98+ # 1. Check relative parts for ignored directories
99+ try :
100+ rel_parts = path_obj .relative_to (self .project_root ).parts
101+ # Ignore common heavy or build directories ONLY if they are inside project root
102+ if any (part in self .ignore_dirs for part in rel_parts ):
103+ return False
104+ except ValueError :
105+ # File is outside project root, ignore it for live reload
97106 return False
98107
99- # 1.6 If it looks like a DB transaction file without an extension, ignore it
100- if any (
101- part .endswith ("-journal" ) or part .endswith ("-wal" ) or part .endswith ("-shm" )
102- for part in path_obj .parts
103- ):
108+ # 2. Ignore specific database, log, and temp file extensions
109+ if path_obj .suffix .lower () in self .ignore_entity_patterns :
104110 return False
105111
106- # 2. Frontend specific ignores
112+ # 3. Ignore DB transaction files without extensions
113+ if any (part .endswith (("-journal" , "-wal" , "-shm" )) for part in rel_parts ):
114+ return False
115+
116+ # 4. Frontend specific ignores (ignore src/assets so HMR handles them)
107117 if self .frontend_dir :
108118 try :
109119 if (
110120 self .frontend_dir in path_obj .parents
111121 or self .frontend_dir == path_obj
112122 ):
113123 rel = path_obj .relative_to (self .frontend_dir )
114- # Ignore source and assets to let HMR handle it
115124 if any (
116125 str (rel ).startswith (p )
117126 for p in ["src" , "public" , "assets" , "node_modules" ]
@@ -120,8 +129,14 @@ def __call__(self, change, path):
120129 except ValueError :
121130 pass
122131
123- # 3. Default filter (ignores binary files, etc.)
124- return super ().__call__ (change , path )
132+ # 5. Ignore hidden files (starting with .) inside the project
133+ # except for the root itself
134+ if any (part .startswith ("." ) and part != "." for part in rel_parts ):
135+ # Special case: allow files in . (the project root) even if they start with . (unlikely)
136+ # Standard pytron practice is to ignore things like .vscode, .idea, etc.
137+ return False
138+
139+ return True
125140
126141
127142def run_dev_mode (script : Path , extra_args : list [str ], engine : str = None ) -> int :
0 commit comments