This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: ftplib behaves oddly if socket timeout is greater than the default
Type: behavior Stage:
Components: IO Versions: Python 3.7, Python 3.6
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: arloclarke, r.david.murray
Priority: normal Keywords:

Created on 2017-07-17 23:05 by arloclarke, last changed 2022-04-11 14:58 by admin.

Messages (5)
msg298565 - (view) Author: Arlo Clarke (arloclarke) Date: 2017-07-17 23:05
Stack overflow question with full details: https://stackoverflow.com/questions/45150568/python-ftp-socket-timeout-handling

Socket timeout in ftplib can't be handled; a program crash occurs even when the relevant code is wrapped in a general catch-all.
msg298567 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2017-07-18 00:53
Given:

import socket
from ftplib import FTP
try:
    ftp = FTP('host.i.know.will.hang.com', timeout=4)
except socket.timeout:
    print('caught')

I see 'caught' printed on the console.  However, if I increase the timeout to 400, then on both 3.5 tip and 3.6 tip I get a TimeoutError, not a socket.timeout.  If I increase the timeout to 4000, I get the TimeoutError in a much shorter time than 4000 seconds.

So, *something* is wrong here.  Looking at the code it isn't obvious what.

Here is the traceback:

Traceback (most recent call last):
  File "../p36/temp.py", line 4, in <module>
    ftp = FTP('xxxx', timeout=4)
  File "/home/rdmurray/python/p35/Lib/ftplib.py", line 118, in __init__
    self.connect(host)
  File "/home/rdmurray/python/p35/Lib/ftplib.py", line 153, in connect
    source_address=self.source_address)
  File "/home/rdmurray/python/p35/Lib/socket.py", line 712, in create_connection
    raise err
  File "/home/rdmurray/python/p35/Lib/socket.py", line 703, in create_connection
    sock.connect(sa)
TimeoutError: [Errno 110] Connection timed out


Your traceback is different because your timeout is occurring after the initial connection.  Are you sure your socket.timeout is the correct one?  You might try printing socket.__file__ to check.
msg298602 - (view) Author: Arlo Clarke (arloclarke) Date: 2017-07-18 16:25
Thanks David. Lowering the timeout to below 60s seems to have resolved this issue. Or at least the error isn't being thrown anymore. I don't know why the error couldn't be handled in the first place, however.
msg298610 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2017-07-18 18:02
I would like to leave this issue open.  It is clear that the behavior for long timeouts does not match the docs, and that should be investigated if someone has the motivation :)
msg298611 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2017-07-18 18:04
I changed the title to reflect the problem, but note that I'm *assuming* it is "greater than the default" that is the issue, I haven't actually tested that theory.
History
Date User Action Args
2022-04-11 14:58:49adminsetgithub: 75139
2017-07-18 18:05:10r.david.murraysettype: crash -> behavior
versions: + Python 3.6, Python 3.7
2017-07-18 18:04:50r.david.murraysetmessages: + msg298611
title: ftplib socket timeout can't be handled -> ftplib behaves oddly if socket timeout is greater than the default
2017-07-18 18:02:55r.david.murraysetstatus: closed -> open
resolution: works for me ->
messages: + msg298610

stage: resolved ->
2017-07-18 16:25:21arloclarkesetstatus: open -> closed
resolution: works for me
messages: + msg298602

stage: resolved
2017-07-18 00:53:31r.david.murraysetnosy: + r.david.murray
messages: + msg298567
2017-07-17 23:05:28arloclarkecreate