@@ -168,7 +168,7 @@ def __call__(self, function_name: OsFunction, args: tuple[Any, ...]) -> Any:
168168 return self .getenv (* args )
169169
170170 @abstractmethod
171- def path_exists (self , path : str ) -> bool :
171+ def path_exists (self , path : PurePosixPath ) -> bool :
172172 """Check if a path exists.
173173
174174 Args:
@@ -180,7 +180,7 @@ def path_exists(self, path: str) -> bool:
180180 raise NotImplementedError
181181
182182 @abstractmethod
183- def path_is_file (self , path : str ) -> bool :
183+ def path_is_file (self , path : PurePosixPath ) -> bool :
184184 """Check if a path is a regular file.
185185
186186 Args:
@@ -192,7 +192,7 @@ def path_is_file(self, path: str) -> bool:
192192 raise NotImplementedError
193193
194194 @abstractmethod
195- def path_is_dir (self , path : str ) -> bool :
195+ def path_is_dir (self , path : PurePosixPath ) -> bool :
196196 """Check if a path is a directory.
197197
198198 Args:
@@ -204,7 +204,7 @@ def path_is_dir(self, path: str) -> bool:
204204 raise NotImplementedError
205205
206206 @abstractmethod
207- def path_is_symlink (self , path : str ) -> bool :
207+ def path_is_symlink (self , path : PurePosixPath ) -> bool :
208208 """Check if a path is a symbolic link.
209209
210210 Args:
@@ -216,7 +216,7 @@ def path_is_symlink(self, path: str) -> bool:
216216 raise NotImplementedError
217217
218218 @abstractmethod
219- def path_read_text (self , path : str ) -> str :
219+ def path_read_text (self , path : PurePosixPath ) -> str :
220220 """Read the contents of a file as text.
221221
222222 Args:
@@ -232,7 +232,7 @@ def path_read_text(self, path: str) -> str:
232232 raise NotImplementedError
233233
234234 @abstractmethod
235- def path_read_bytes (self , path : str ) -> bytes :
235+ def path_read_bytes (self , path : PurePosixPath ) -> bytes :
236236 """Read the contents of a file as bytes.
237237
238238 Args:
@@ -248,7 +248,7 @@ def path_read_bytes(self, path: str) -> bytes:
248248 raise NotImplementedError
249249
250250 @abstractmethod
251- def path_write_text (self , path : str , data : str ) -> None :
251+ def path_write_text (self , path : PurePosixPath , data : str ) -> None :
252252 """Write text data to a file.
253253
254254 Args:
@@ -262,7 +262,7 @@ def path_write_text(self, path: str, data: str) -> None:
262262 raise NotImplementedError
263263
264264 @abstractmethod
265- def path_write_bytes (self , path : str , data : bytes ) -> None :
265+ def path_write_bytes (self , path : PurePosixPath , data : bytes ) -> None :
266266 """Write binary data to a file.
267267
268268 Args:
@@ -276,7 +276,7 @@ def path_write_bytes(self, path: str, data: bytes) -> None:
276276 raise NotImplementedError
277277
278278 @abstractmethod
279- def path_mkdir (self , path : str , parents : bool , exist_ok : bool ) -> None :
279+ def path_mkdir (self , path : PurePosixPath , parents : bool , exist_ok : bool ) -> None :
280280 """Create a directory.
281281
282282 Args:
@@ -291,7 +291,7 @@ def path_mkdir(self, path: str, parents: bool, exist_ok: bool) -> None:
291291 raise NotImplementedError
292292
293293 @abstractmethod
294- def path_unlink (self , path : str ) -> None :
294+ def path_unlink (self , path : PurePosixPath ) -> None :
295295 """Remove a file.
296296
297297 Args:
@@ -304,7 +304,7 @@ def path_unlink(self, path: str) -> None:
304304 raise NotImplementedError
305305
306306 @abstractmethod
307- def path_rmdir (self , path : str ) -> None :
307+ def path_rmdir (self , path : PurePosixPath ) -> None :
308308 """Remove an empty directory.
309309
310310 Args:
@@ -318,7 +318,7 @@ def path_rmdir(self, path: str) -> None:
318318 raise NotImplementedError
319319
320320 @abstractmethod
321- def path_iterdir (self , path : str ) -> list [PurePosixPath ]:
321+ def path_iterdir (self , path : PurePosixPath ) -> list [PurePosixPath ]:
322322 """List the contents of a directory.
323323
324324 Args:
@@ -334,7 +334,7 @@ def path_iterdir(self, path: str) -> list[PurePosixPath]:
334334 raise NotImplementedError
335335
336336 @abstractmethod
337- def path_stat (self , path : str ) -> StatResult :
337+ def path_stat (self , path : PurePosixPath ) -> StatResult :
338338 """Get file status information.
339339
340340 Use file_stat(), dir_stat(), or symlink_stat() helpers to create the return value.
@@ -351,7 +351,7 @@ def path_stat(self, path: str) -> StatResult:
351351 raise NotImplementedError
352352
353353 @abstractmethod
354- def path_rename (self , path : str , target : str ) -> None :
354+ def path_rename (self , path : PurePosixPath , target : PurePosixPath ) -> None :
355355 """Rename a file or directory.
356356
357357 Args:
@@ -365,7 +365,7 @@ def path_rename(self, path: str, target: str) -> None:
365365 raise NotImplementedError
366366
367367 @abstractmethod
368- def path_resolve (self , path : str ) -> str :
368+ def path_resolve (self , path : PurePosixPath ) -> str :
369369 """Resolve a path to an absolute path, resolving any symlinks.
370370
371371 Args:
@@ -377,7 +377,7 @@ def path_resolve(self, path: str) -> str:
377377 raise NotImplementedError
378378
379379 @abstractmethod
380- def path_absolute (self , path : str ) -> str :
380+ def path_absolute (self , path : PurePosixPath ) -> str :
381381 """Convert a path to an absolute path without resolving symlinks.
382382
383383 Args:
@@ -692,40 +692,40 @@ def __init__(
692692 def __repr__ (self ) -> str :
693693 return f'OSAccess(files={ self .files } , environ={ self .environ } )'
694694
695- def path_exists (self , path : str ) -> bool :
695+ def path_exists (self , path : PurePosixPath ) -> bool :
696696 return self ._get_entry (path ) is not None
697697
698- def path_is_file (self , path : str ) -> bool :
698+ def path_is_file (self , path : PurePosixPath ) -> bool :
699699 return _is_file (self ._get_entry (path ))
700700
701- def path_is_dir (self , path : str ) -> bool :
701+ def path_is_dir (self , path : PurePosixPath ) -> bool :
702702 return _is_dir (self ._get_entry (path ))
703703
704- def path_is_symlink (self , path : str ) -> bool :
704+ def path_is_symlink (self , path : PurePosixPath ) -> bool :
705705 return False
706706
707- def path_read_text (self , path : str ) -> str :
707+ def path_read_text (self , path : PurePosixPath ) -> str :
708708 file = self ._get_file (path )
709709 content = file .read_content ()
710710 return content if isinstance (content , str ) else content .decode ()
711711
712- def path_read_bytes (self , path : str ) -> bytes :
712+ def path_read_bytes (self , path : PurePosixPath ) -> bytes :
713713 file = self ._get_file (path )
714714 content = file .read_content ()
715715 return content if isinstance (content , bytes ) else content .encode ()
716716
717- def path_write_text (self , path : str , data : str ) -> None :
717+ def path_write_text (self , path : PurePosixPath , data : str ) -> None :
718718 self ._write_file (path , data )
719719
720- def path_write_bytes (self , path : str , data : bytes ) -> None :
720+ def path_write_bytes (self , path : PurePosixPath , data : bytes ) -> None :
721721 self ._write_file (path , data )
722722
723- def _write_file (self , path : str , data : bytes | str ) -> None :
723+ def _write_file (self , path : PurePosixPath , data : bytes | str ) -> None :
724724 entry = self ._get_entry (path )
725725 if _is_file (entry ):
726726 entry .write_content (data )
727727 elif _is_dir (entry ):
728- raise IsADirectoryError (f'[Errno 21] Is a directory: { path !r} ' )
728+ raise IsADirectoryError (f'[Errno 21] Is a directory: { str ( path ) !r} ' )
729729
730730 # write a new file if the parent directory exists
731731 parent_entry = self ._parent_entry (path )
@@ -734,58 +734,58 @@ def _write_file(self, path: str, data: bytes | str) -> None:
734734 parent_entry [file_path .name ] = new_file = MemoryFile (file_path , data )
735735 self .files .append (new_file )
736736 else :
737- raise FileNotFoundError (f'[Errno 2] No such file or directory: { path !r} ' )
737+ raise FileNotFoundError (f'[Errno 2] No such file or directory: { str ( path ) !r} ' )
738738
739- def path_mkdir (self , path : str , parents : bool , exist_ok : bool ) -> None :
739+ def path_mkdir (self , path : PurePosixPath , parents : bool , exist_ok : bool ) -> None :
740740 entry = self ._get_entry (path )
741741 if _is_file (entry ):
742- raise FileExistsError (f'[Errno 17] File exists: { path !r} ' )
742+ raise FileExistsError (f'[Errno 17] File exists: { str ( path ) !r} ' )
743743 elif _is_dir (entry ):
744744 if exist_ok :
745745 return
746746 else :
747- raise FileExistsError (f'[Errno 17] File exists: { path !r} ' )
747+ raise FileExistsError (f'[Errno 17] File exists: { str ( path ) !r} ' )
748748
749749 parent_entry = self ._parent_entry (path )
750750 if _is_dir (parent_entry ):
751751 parent_entry [PurePosixPath (path ).name ] = {}
752752 return
753753 elif _is_file (parent_entry ):
754- raise NotADirectoryError (f'[Errno 20] Not a directory: { path !r} ' )
754+ raise NotADirectoryError (f'[Errno 20] Not a directory: { str ( path ) !r} ' )
755755 elif parents :
756756 subtree = self ._tree
757757 for part in PurePosixPath (path ).parts :
758758 entry = subtree .setdefault (part , {})
759759 if _is_dir (entry ):
760760 subtree = entry
761761 else :
762- raise NotADirectoryError (f'[Errno 20] Not a directory: { path !r} ' )
762+ raise NotADirectoryError (f'[Errno 20] Not a directory: { str ( path ) !r} ' )
763763 else :
764- raise FileNotFoundError (f'[Errno 2] No such file or directory: { path !r} ' )
764+ raise FileNotFoundError (f'[Errno 2] No such file or directory: { str ( path ) !r} ' )
765765
766- def path_unlink (self , path : str ) -> None :
766+ def path_unlink (self , path : PurePosixPath ) -> None :
767767 file = self ._get_file (path )
768768 file .delete ()
769769 # remove from parent
770770 parent_dir = self ._parent_entry (path )
771771 assert _is_dir (parent_dir ), f'Expected parent of a file to always be a directory, got { parent_dir } '
772772 del parent_dir [file .name ]
773773
774- def path_rmdir (self , path : str ) -> None :
774+ def path_rmdir (self , path : PurePosixPath ) -> None :
775775 dir = self ._get_dir (path )
776776 if dir :
777- raise OSError (f'[Errno 39] Directory not empty: { path !r} ' )
777+ raise OSError (f'[Errno 39] Directory not empty: { str ( path ) !r} ' )
778778 # remove from parent
779779 parent_dir = self ._parent_entry (path )
780780 assert _is_dir (parent_dir ), f'Expected parent of a file to always be a directory, got { parent_dir } '
781781 del parent_dir [PurePosixPath (path ).name ]
782782
783- def path_iterdir (self , path : str ) -> list [PurePosixPath ]:
783+ def path_iterdir (self , path : PurePosixPath ) -> list [PurePosixPath ]:
784784 # Return full paths as PurePosixPath objects (will be converted to MontyObject::Path)
785785 dir_path = PurePosixPath (path )
786786 return [dir_path / name for name in self ._get_dir (path ).keys ()]
787787
788- def path_stat (self , path : str ) -> StatResult :
788+ def path_stat (self , path : PurePosixPath ) -> StatResult :
789789 entry = self ._get_entry_exists (path )
790790 if _is_file (entry ):
791791 content = entry .read_content ()
@@ -794,22 +794,22 @@ def path_stat(self, path: str) -> StatResult:
794794 else :
795795 return StatResult .dir_stat ()
796796
797- def path_rename (self , path : str , target : str ) -> None :
797+ def path_rename (self , path : PurePosixPath , target : PurePosixPath ) -> None :
798798 src_entry = self ._get_entry (path )
799799 if src_entry is None :
800- raise FileNotFoundError (f'[Errno 2] No such file or directory: { path } -> { target } ' )
800+ raise FileNotFoundError (f'[Errno 2] No such file or directory: { str ( path )!r } -> { str ( target )!r } ' )
801801
802802 parent_dir = self ._parent_entry (path )
803803 assert _is_dir (parent_dir ), f'Expected parent of a file to always be a directory, got { parent_dir } '
804804
805805 target_parent = self ._parent_entry (target )
806806 if not _is_dir (target_parent ):
807- raise FileNotFoundError (f'[Errno 2] No such file or directory: { path } -> { target } ' )
807+ raise FileNotFoundError (f'[Errno 2] No such file or directory: { str ( path )!r } -> { str ( target )!r } ' )
808808 target_entry = self ._get_entry (target )
809809
810810 if _is_file (src_entry ):
811811 if _is_dir (target_entry ):
812- raise IsADirectoryError (f'[Errno 21] Is a directory: { path } -> { target } ' )
812+ raise IsADirectoryError (f'[Errno 21] Is a directory: { str ( path )!r } -> { str ( target )!r } ' )
813813 if _is_file (target_entry ):
814814 # need to mark the target as deleted as it'll be overwritten
815815 target_entry .delete ()
@@ -823,9 +823,9 @@ def path_rename(self, path: str, target: str) -> None:
823823 else :
824824 assert _is_dir (src_entry ), 'src path must be a directory here'
825825 if _is_file (target_entry ):
826- raise NotADirectoryError (f'[Errno 20] Not a directory: { path } -> { target } ' )
826+ raise NotADirectoryError (f'[Errno 20] Not a directory: { str ( path )!r } -> { str ( target )!r } ' )
827827 elif _is_dir (target_entry ) and target_entry :
828- raise OSError (f'[Errno 66] Directory not empty: { path } -> { target } ' )
828+ raise OSError (f'[Errno 66] Directory not empty: { str ( path )!r } -> { str ( target )!r } ' )
829829
830830 src_name = PurePosixPath (path ).name
831831 target_name = PurePosixPath (target ).name
@@ -837,11 +837,11 @@ def path_rename(self, path: str, target: str) -> None:
837837 # Update paths for all files in the renamed directory
838838 self ._update_paths_recursive (src_entry , PurePosixPath (path ), PurePosixPath (target ))
839839
840- def path_resolve (self , path : str ) -> str :
840+ def path_resolve (self , path : PurePosixPath ) -> str :
841841 # No symlinks in OSAccess, so resolve is same as absolute with normalization
842842 return self .path_absolute (path )
843843
844- def path_absolute (self , path : str ) -> str :
844+ def path_absolute (self , path : PurePosixPath ) -> str :
845845 p = PurePosixPath (path )
846846 if p .is_absolute ():
847847 return str (p )
@@ -851,7 +851,7 @@ def path_absolute(self, path: str) -> str:
851851 def getenv (self , key : str , default : str | None = None ) -> str | None :
852852 return self .environ .get (key , default )
853853
854- def _get_entry (self , path : str ) -> Tree | AbstractFile | None :
854+ def _get_entry (self , path : PurePosixPath ) -> Tree | AbstractFile | None :
855855 dir = self ._tree
856856
857857 * dir_parts , name = PurePosixPath (path ).parts
@@ -865,29 +865,29 @@ def _get_entry(self, path: str) -> Tree | AbstractFile | None:
865865
866866 return dir .get (name )
867867
868- def _get_entry_exists (self , path : str ) -> Tree | AbstractFile :
868+ def _get_entry_exists (self , path : PurePosixPath ) -> Tree | AbstractFile :
869869 entry = self ._get_entry (path )
870870 if entry is None :
871- raise FileNotFoundError (f'[Errno 2] No such file or directory: { path !r} ' )
871+ raise FileNotFoundError (f'[Errno 2] No such file or directory: { str ( path ) !r} ' )
872872 else :
873873 return entry
874874
875- def _get_file (self , path : str ) -> AbstractFile :
875+ def _get_file (self , path : PurePosixPath ) -> AbstractFile :
876876 entry = self ._get_entry_exists (path )
877877 if _is_file (entry ):
878878 return entry
879879 else :
880- raise IsADirectoryError (f'[Errno 21] Is a directory: { path !r} ' )
880+ raise IsADirectoryError (f'[Errno 21] Is a directory: { str ( path ) !r} ' )
881881
882- def _get_dir (self , path : str ) -> Tree :
882+ def _get_dir (self , path : PurePosixPath ) -> Tree :
883883 entry = self ._get_entry_exists (path )
884884 if _is_dir (entry ):
885885 return entry
886886 else :
887- raise NotADirectoryError (f'[Errno 20] Not a directory: { path !r} ' )
887+ raise NotADirectoryError (f'[Errno 20] Not a directory: { str ( path ) !r} ' )
888888
889- def _parent_entry (self , path : str ) -> Tree | AbstractFile | None :
890- return self ._get_entry (str ( PurePosixPath (path ).parent ) )
889+ def _parent_entry (self , path : PurePosixPath ) -> Tree | AbstractFile | None :
890+ return self ._get_entry (PurePosixPath (path ).parent )
891891
892892 def _update_paths_recursive (self , tree : Tree , old_prefix : PurePosixPath , new_prefix : PurePosixPath ) -> None :
893893 """Update path attributes for all files in a tree after directory rename.
0 commit comments