15
15
from . import config , formats , hooks
16
16
from .converters import Converter , List , map_type , resolve
17
17
from .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
19
19
20
20
21
21
class Mapper :
@@ -45,6 +45,7 @@ def __init__(
45
45
self ._last_load = 0.0
46
46
self ._last_data : Dict = {}
47
47
self ._root = root
48
+ self ._original_path = None
48
49
49
50
@property
50
51
def classname (self ) -> str :
@@ -58,7 +59,13 @@ def path(self) -> Optional[Path]:
58
59
path = Path (self ._pattern .format (self = self ._instance )).expanduser ()
59
60
if path .is_absolute () or self ._pattern .startswith ("./" ):
60
61
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
62
69
63
70
cls = self ._instance .__class__
64
71
try :
@@ -69,6 +76,8 @@ def path(self) -> Optional[Path]:
69
76
root = Path .cwd ()
70
77
71
78
path = (root / path ).resolve ()
79
+ if self ._original_path is None :
80
+ self ._original_path = path
72
81
log .debug (f"Detected dynamic pattern: { path } " )
73
82
return path
74
83
@@ -264,6 +273,15 @@ def save(self, *, include_default_values: Trilean = None, _log=True) -> None:
264
273
self ._root .save (include_default_values = include_default_values , _log = _log )
265
274
return
266
275
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
+
267
285
if self .path :
268
286
if self .exists and self ._frozen :
269
287
raise dataclasses .FrozenInstanceError (
@@ -279,6 +297,9 @@ def save(self, *, include_default_values: Trilean = None, _log=True) -> None:
279
297
text = self ._get_text (include_default_values = include_default_values )
280
298
281
299
write (self .path , text , display = True )
300
+ if file_rename_required :
301
+ remove (self ._original_path )
302
+ self ._original_path = self .path
282
303
283
304
self .modified = False
284
305
0 commit comments