~sschwarzer/ftputil#150: 
Invalidate cache in rename method

Python 3.7.2 ftputil 5.0.2

I'm renaming an existing file, and then calling .path.exists(path) do check if old file does not exist. But exists and other methods, like stat, returns cached data about already deleted file:

ftpHost.path.exists("/ftp/file.tmp")  # False
ftpHost.upload("/my/local/file", "/ftp/file.tmp")
ftpHost.path.exists("/ftp/file.tmp")  # True
ftpHost.rename("/ftp/file.tmp", "/ftp/file")
ftpHostt.path.exists("/ftp/file")  # True

This is because rename method does not invalidate the cache:

--- a/ftputil/host.py
+++ b/ftputil/host.py
@@ -892,6 +892,8 @@ class FTPHost:
         self._check_inaccessible_login_directory()
         source_head, source_tail = self.path.split(source)
+        source_absolute_path = self.path.abspath(source)
         target_head, target_tail = self.path.split(target)
+        target_absolute_path = self.path.abspath(target)
         paths_contain_whitespace = (" " in source_head) or (" " in target_head)
         if paths_contain_whitespace and source_head == target_head:
             # Both items are in the same directory.
@@ -906,6 +908,8 @@ class FTPHost:
             # Use straightforward command.
             with ftputil.error.ftplib_error_to_ftp_os_error:
                 self._session.rename(source, target)
+        self.stat_cache.invalidate(source_absolute_path)
+        self.stat_cache.invalidate(target_absolute_path)
 
     # XXX: One could argue to put this method into the `_Stat` class, but I
     # refrained from that because then `_Stat` would have to know about
Status
RESOLVED FIXED
Submitter
~dolfinus
Assigned to
Submitted
2 years ago
Updated
2 years ago
Labels
No labels applied.

~sschwarzer 2 years ago*

Hello ~dolfinus, thanks for the report and the patch! I plan to work on the ticket (including test updates) next weekend.

~dolfinus 2 years ago

~sschwarzer I've checked changes you made, it's working now. Thanks!

~sschwarzer REPORTED FIXED 2 years ago

Thanks for the feedback! :-)

Changes in the recent commits:

  • Invalidate stat cache entries in FTPHost.rename.
  • In FTPHost.remove, FTPHost.rmdir, FTPHost.rmtree and FTPHost.rename: If an exception occurs during the operation, invalidate the cache for the affected file system items. The idea is that even if there was an exception, the server might have finished the operation but failed when responding.

~sschwarzer 2 years ago

Released ftputil 5.0.4 with the fix.

Register here or Log in to comment, or comment via email.