Reputation: 4927
I have this python function to upload file through sftp. It works fine.
def sftp_upload(destination, username, password,
remote_loc, source_file):
import pysftp
with pysftp.Connection(destination, username,
password, log="pysftp.log") as sftp:
sftp.cwd(remote_loc)
sftp.put(source_file)
sftp.close()
return None
The code works as expected. However, I always receive this error at the end ImportError: sys.meta_path is None, Python is likely shutting down
.
How to remove this error? I'm also puzzled why code runs smoothly to the end despite the error.
In the log file, I saw the following;
INF [20220304-18:49:14.727] thr=2 paramiko.transport.sftp: [chan 0] sftp session closed.
DEB [20220304-18:49:14.727] thr=2 paramiko.transport: [chan 0] EOF sent (0)
DEB [20220304-18:49:14.728] thr=1 paramiko.transport: EOF in transport thread
Here's the stack trace;
Exception ignored in: <function Connection.__del__ at 0x000001A8B08765E0>
Traceback (most recent call last):
File "C:\ProgramData\Anaconda3\lib\site-packages\pysftp\__init__.py", line 1013, in __del__
File "C:\ProgramData\Anaconda3\lib\site-packages\pysftp\__init__.py", line 795, in close
ImportError: sys.meta_path is None, Python is likely shutting down
I am using python v3.9
Upvotes: 0
Views: 1350
Reputation: 43103
Note: import pysftp
outside the function somehow resolves the issue for me. 🤔
It's a bug in pysftp==0.2.9
.
You can fix it by overriding close()
to only run once:
class SFTPConnection(pysftp.Connection):
def close(self):
if getattr(self, '_closed', False):
return
self._closed = True
super().close()
Usage:
# with pysftp.Connection(destination, username, password=password, log="pysftp.log") as sftp: # -
with SFTPConnection(destination, username, password=password, log="pysftp.log") as sftp: # +
References:
Upvotes: 2
Reputation: 554
It looks like your program ends before the sftp
object is garbage-collected.
Then, the sftp.__del__
method is called at the middle of the program's teardown, which is causing the error.
From pysftp.py code:
def __del__(self):
"""Attempt to clean up if not explicitly closed."""
self.close()
I personally think that it should be considered as a bug in the pysftp project.
I can think of two workarounds:
Override the __del__
method:
pysftp.Connection.__del__ = lambda x: None
(Less recomended - less efficient) Explicitly delete the sftp
object and trigger garbage collection:
del sftp; import gc; gc.collect()
right after the with
block
Upvotes: 1