1515from . import config , formats , hooks
1616from .converters import Converter , List , map_type , resolve
1717from .types import Missing , Trilean
18- from .utils import display , get_default_field_value , recursive_update , write
18+ from .utils import display , get_default_field_value , recursive_update , write , remove
1919
2020
2121class Mapper :
@@ -45,6 +45,7 @@ def __init__(
4545 self ._last_load = 0.0
4646 self ._last_data : Dict = {}
4747 self ._root = root
48+ self ._original_path = None
4849
4950 @property
5051 def classname (self ) -> str :
@@ -58,7 +59,13 @@ def path(self) -> Optional[Path]:
5859 path = Path (self ._pattern .format (self = self ._instance )).expanduser ()
5960 if path .is_absolute () or self ._pattern .startswith ("./" ):
6061 log .debug (f"Detected static pattern: { path } " )
61- return path .resolve ()
62+
63+ resolved_path = path .resolve ()
64+
65+ if self ._original_path is None :
66+ self ._original_path = resolved_path
67+
68+ return resolved_path
6269
6370 cls = self ._instance .__class__
6471 try :
@@ -69,6 +76,8 @@ def path(self) -> Optional[Path]:
6976 root = Path .cwd ()
7077
7178 path = (root / path ).resolve ()
79+ if self ._original_path is None :
80+ self ._original_path = path
7281 log .debug (f"Detected dynamic pattern: { path } " )
7382 return path
7483
@@ -264,6 +273,15 @@ def save(self, *, include_default_values: Trilean = None, _log=True) -> None:
264273 self ._root .save (include_default_values = include_default_values , _log = _log )
265274 return
266275
276+ # Determine whether the attributes that are involved in the path were changed
277+ file_rename_required = False
278+ with hooks .disabled (): # hooks have to be disabled to prevent infinite loop
279+ if "path" in self .__dict__ :
280+ del self .__dict__ ["path" ] # invalidate the cached property
281+
282+ if self ._original_path is not None and self .path != self ._original_path :
283+ file_rename_required = True
284+
267285 if self .path :
268286 if self .exists and self ._frozen :
269287 raise dataclasses .FrozenInstanceError (
@@ -279,6 +297,9 @@ def save(self, *, include_default_values: Trilean = None, _log=True) -> None:
279297 text = self ._get_text (include_default_values = include_default_values )
280298
281299 write (self .path , text , display = True )
300+ if file_rename_required :
301+ remove (self ._original_path )
302+ self ._original_path = self .path
282303
283304 self .modified = False
284305
0 commit comments