You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
intermittent ResourceWarning in test_ftplib #131888
The issue is due to SSLConnection overriding close() to initiate a tls shutdown, however the asyncore interface requires .close() to close the underlying connection synchronously.
For tls shutdown to close the socket, it must poll the selector and retry the socket.unwrap() call, and then worse asyncore.close_all() needs to be called again on the unwrapped socket.
In the unittest tearDown only .close() is called, and only once - not the required N+1 times and without waiting for readability or writeability on the socket.
In my PR I split the close behaviour into .close() for killing the connection and .shutdown() for initiating an unwrap. All internally initiated closes use shutdown because they can wait using the selector. External closes use the original hard close method from the super class
Probably we can get away with only one call to asyncore.close_all() and rely on it to work when joining the thread.
Activity
graingert commentedon Mar 30, 2025
I have a fix, I think
pythongh-131888: fix ResourceWarning in test_ftplib
graingert commentedon Mar 30, 2025
The issue is due to SSLConnection overriding close() to initiate a tls shutdown, however the asyncore interface requires .close() to close the underlying connection synchronously.
For tls shutdown to close the socket, it must poll the selector and retry the socket.unwrap() call, and then worse asyncore.close_all() needs to be called again on the unwrapped socket.
In the unittest tearDown only .close() is called, and only once - not the required N+1 times and without waiting for readability or writeability on the socket.
In my PR I split the close behaviour into .close() for killing the connection and .shutdown() for initiating an unwrap. All internally initiated closes use shutdown because they can wait using the selector. External closes use the original hard close method from the super class
Probably we can get away with only one call to asyncore.close_all() and rely on it to work when joining the thread.
gh-131888: fix ResourceWarning in test_ftplib (#131889)
pythongh-131888: fix ResourceWarning in test_ftplib (pythonGH-131889)
pythongh-131888: fix ResourceWarning in test_ftplib (pythonGH-131889)
[3.12] gh-131888: fix ResourceWarning in test_ftplib (GH-131889) (#13…
[3.13] gh-131888: fix ResourceWarning in test_ftplib (GH-131889) (#13…