Skip to content

intermittent ResourceWarning in test_ftplib #131888

Closed

Description

@graingert

Hi! The buildbot PPC64LE Fedora Stable LTO 3.13 (tier-2) has failed when building commit 07d4c7e.

You can take a look at the buildbot page here:

https://buildbot.python.org/#/builders/1492/builds/501

Summary of the results of the build (if available):

Traceback (most recent call last):
  File "/home/buildbot/buildarea/3.13.cstratak-fedora-stable-ppc64le.lto/build/Lib/test/test_ftplib.py", line 935, in tearDown
    self.server = None
ResourceWarning: unclosed <ssl.SSLSocket fd=6, family=2, type=1, proto=0, laddr=('127.0.0.1', 39543), raddr=('127.0.0.1', 54764)>
k


Traceback (most recent call last):
  File "/home/buildbot/buildarea/3.13.cstratak-fedora-stable-ppc64le.lto/build/Lib/test/test_ftplib.py", line 935, in tearDown
    self.server = None
ResourceWarning: unclosed <ssl.SSLSocket fd=5, family=2, type=1, proto=0, laddr=('127.0.0.1', 43007), raddr=('127.0.0.1', 49844)>
k

Originally posted by @bedevere-bot in #131802 (comment)

Linked PRs

Activity

  1. graingert commented on Mar 30, 2025

    @graingert
    ContributorAuthor

    I have a fix, I think

  2. added a commit that references this issue on Mar 30, 2025
  3. graingert commented on Mar 30, 2025

    @graingert
    ContributorAuthor

    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.

  4. added
    type-bugAn unexpected behavior, bug, or error
    testsTests in the Lib/test dir
    on Mar 30, 2025
  5. added a commit that references this issue on Apr 2, 2025
  6. added 2 commits that reference this issue on Apr 2, 2025
  7. added 2 commits that reference this issue on Apr 2, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    testsTests in the Lib/test dirtype-bugAn unexpected behavior, bug, or error

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions