2

Based on the docs and all previous SO questions, the code here should work properly, but isn't. Couldn't find any duplicates. If there are, my bad.

Basically, after calling ftp.quit() on a valid ftp connection, subsequent attempts to test whether it is connected fail. Running the try / except block below prior to ftp.quit() works properly ("Connection is open" is always printed).

After closing the connection using ftp.quit():

1. I tried catching errors when calling ftp.voidcmd('NOOP').

I get an Attribute: NoneType... error (which should be an indication that the ftp object reset to None).

2. But, checking if ftp is None also fails.

3: And, just for additional confirmation, I check type(ftp)

Code to reproduce: (Result follows)

# Connect
import ftplib
ftp = ftplib.FTP("FtpSite")
ftp.login("user","passwd")

# show success
print(ftp.getwelcome())

connected = True

# Close connection
ftp.quit()

# Is ftp still a valid obj?
print(type(ftp))

# Is ftp None?
if ftp is None:
    print("ftp is None.")
else:
    print("ftp is still assigned, but closed")


# check if open
try:
    ftp.voidcmd("NOOP")
except ftplib.all_errors as e:
    errorInfo = str(e).split(None, 1)[0]
    print(errorInfo)
    connected = False

if connected:
    print("Connection is open.")
else:
    print("Connection already closed.")

Result:

<class 'ftplib.FTP'>  # the output of print(type(ftp))

ftp is still assigned, but closed  # the output of checking if None  

Traceback (most recent call last):  # the output of calling ftp.voidcmd()
  File "./dailyfetch.py", line 27, in <module>
    ftp.voidcmd("NOOP")
  File "C:\python37\lib\ftplib.py", line 277, in voidcmd
    self.putcmd(cmd)
  File "C:\python37\lib\ftplib.py", line 199, in putcmd
    self.putline(line)
  File "C:\python37\lib\ftplib.py", line 194, in putline
    self.sock.sendall(line.encode(self.encoding))
AttributeError: 'NoneType' object has no attribute 'sendall'

Related SO questions: Checking a Python FTP connection How to "test" NoneType in python?

Docs: https://docs.python.org/3/library/ftplib.html

Josh21
  • 506
  • 5
  • 15
Rick C137
  • 21
  • 4

1 Answers1

2

I know this is an old thread.

The issue is that the Exception raised is not an ftplib error, but instead an AttributeError from the socket that is being used.

Try changing ftplib.all_errors to AtributeError.

Full code:

# Connect
import ftplib
ftp = ftplib.FTP("FtpSite")
ftp.login("user","passwd")

# show success
print(ftp.getwelcome())

connected = True

# Close connection
ftp.quit()

# Is ftp still a valid obj?
print(type(ftp))

# Is ftp None?
if ftp is None:
    print("ftp is None.")
else:
    print("ftp is still assigned, but closed")


# check if open
try:
    ftp.voidcmd("NOOP")
except AttributeError as e:
    errorInfo = str(e).split(None, 1)[0]
    print(errorInfo)
    connected = False

if connected:
    print("Connection is open.")
else:
    print("Connection already closed.")

Output:

220-Matrix FTP server ready.
<class 'ftplib.FTP'>
ftp is still assigned, but closed
'NoneType'
Connection already closed.

EDIT:

The "None" object is the socket, not the ftp object, which you can see by doing type(ftp.sock). Having run ftp.quit(), this returns <class 'NoneType'>. Before this, however, it returns <class 'socket.socket'>, which you could use as another test which is similar to your test for checking if ftp is None, ie:

# Is ftp.sock None?
if ftp.sock is None:
    print("Socket is None.")
else:
    print("Socket is still assigned, but closed")
Ed Ward
  • 2,333
  • 2
  • 10
  • 16