#151 SFTP support (FTPS is already supported!) 2 years ago

on ~sschwarzer/ftputil

Hi ~dolfinus :-)

Well, there is https://docs.paramiko.org/en/stable/api/sftp.html

Yes, I mentioned/discussed it in the ticket description. :-)

I think the topic is rather complicated, so at least at the moment it doesn't seem worth it to work on Paramiko integration in ftputil.

Of course, and maybe that's what you meant, if someone needs "just" SFTP support without compatibility with the ftputil API, they may be fine with using Paramiko's SFTP class directly.

#151 SFTP support (FTPS is already supported!) 2 years ago

Comment by ~dolfinus on ~sschwarzer/ftputil

#150 Invalidate cache in rename method 2 years ago

Comment by ~dolfinus on ~sschwarzer/ftputil

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

#150 Invalidate cache in rename method 2 years ago

Ticket created by ~dolfinus on ~sschwarzer/ftputil

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