FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

imaplib 3.14 regression: IMAP4.file became read-only property, breaking subclass overrides (affects imapclient IMAP4_TLS) · Issue #142307 · python/cpython · GitHub

Repository navigation

imaplib 3.14 regression: IMAP4.file became read-only property, breaking subclass overrides (affects imapclient IMAP4_TLS) #142307

Closed as not planned

Description

Bug report

Bug description:

In Python 3.14, imaplib.IMAP4.file was changed from a normal attribute to a read-only property.
This breaks legitimate subclassing patterns used by third-party libraries such as imapclient, which override open() and assign to self.file.

Example failure

Running imapclient’s IMAP4_TLS on Python 3.14 produces:

AttributeError: property 'file' of 'IMAP4_TLS' object has no setter

Regression cause

In Python 3.14, imaplib.IMAP4.file was changed to:

 @property
    def file(self):
        # The old 'file' attribute is no longer used now that we do our own
        # read() and readline() buffering, with which it conflicts.
        # As an undocumented interface, it should never have been accessed by
        # external code, and therefore does not warrant deprecation.
        # Nevertheless, we provide this property for now, to avoid suddenly
        # breaking any code in the wild that might have been using it in a
        # harmless way.
        import warnings
        warnings.warn(
            'IMAP4.file is unsupported, can cause errors, and may be removed.',
            RuntimeWarning,
            stacklevel=2)
        return self._file

with no setter provided.

https://github.com/python/cpython/blob/3.14/Lib/imaplib.py#L319-L333

Prior to 3.14, file was a normal attribute and writable.

 def open(self, host='', port=IMAP4_PORT, timeout=None):
        """Setup connection to remote server on "host:port"
            (default: localhost:standard IMAP4 port).
        This connection will be used by the routines:
            read, readline, send, shutdown.
        """
        self.host = host
        self.port = port
        self.sock = self._create_socket(timeout)
        self.file = self.sock.makefile('rb')

https://github.com/python/cpython/blob/3.13/Lib/imaplib.py#L307-L316

Why this is a compatibility break

Even though file was undocumented, turning a previously writable instance attribute into a read-only property introduces a silent backward-incompatible change for:

  • Subclasses which override the I/O layer
  • SSL/TLS IMAP wrappers such as imapclient’s IMAP4_TLS
  • Any code that monkeypatches or replaces the socket reader

Making file immutable removes the ability to replace the buffered reader the base class uses.

Expected behavior

At minimum, subclass overrides should continue to work.
Options include:

  1. Add a setter to the property that writes to _file
  2. Or rename the internal attribute (e.g., _imaplib_file) instead of shadowing a long-existing public attribute name
  3. Or provide an explicit API for replacing the buffered input stream
  4. Or adjust the documentation to specify expected subclass hooks and ensure compatibility

Impact

This change breaks:

  • imapclient (over 1 million downloads per month)
  • Libraries layered on top of imapclient, including mailsuite and parsedmarc
  • All users of IMAP SSL/TLS wrappers relying on custom socket readers

The imapclient maintainers have an open issue tracking this:
mjs/imapclient#618

parsedmarc has an open issue here: domainaware/parsedmarc#636

Request

Please consider restoring backward compatibility by adding a setter or by adjusting the refactor so that subclass assignment to self.file is still possible.

CPython versions tested on:

3.14

Operating systems tested on:

No response

Linked PRs

Activity

  1. self-assigned this
    on Dec 6, 2025
  2. picnixz commented on Dec 6, 2025

    Member

    So I've been trying various approaches and there are few issues:

    • While I understand that the package is popular, it's not been updated since 2023 and doesn't officially support Python 3.14.
    • Making it a different attribute so that people can do whatever they want with their 'file' is also not a good idea because imapclient uses the super shutdown() which calls self.file.close(). So if we renamed the attribute, it would become self._imaplib_file.close() and the file created by imapclient would still be opened.
    • Making it writable again is annoying because we really don't want to use that attribute actually. If a connection is open, then sock and file are set but need to be synchronized. When opening an SSL connection, we wrap the socket and recreate the file. This is also an issue in our current code where we should have closed the previous file before wrapping the socket. I'm not sure the destructor automatically closes the SocketIO object (that could be annoying!)

    I'm inclined to actually not change anything and ask maintainers of imapclient to fix the library. However, I can make it writable again and document that using it is at their own risk. Fixing the synchronization issue is honestly not that interesting either since I prefer removing the attribute altogether in the future so a deprecation is better for Python 3.15. I'll restore the behavior for Python 3.14.


    Or rename the internal attribute (e.g., _imaplib_file) instead of shadowing a long-existing public attribute

    As per PEP-8, it's not a public attribute. Something that is not documented is not considered part of the public API.

    Or adjust the documentation to specify expected subclass hooks and ensure compatibility

    The compatibility was never really supported because of the previous file not being closed.

  3. added 2 commits that reference this issue on Dec 6, 2025
  4. added
    3.14bugs and security fixes
    3.15bugs and security fixes
    on Dec 6, 2025
  5. seanthegeek commented on Dec 6, 2025

    Author

    As I read through this whole situation more, yeah. It should really be on the maintainers of imapclient to use an approach that does not use file for something it wasn't intended for. I'm just not sure what that fix would be on their end. Although the repo for that project has shown activity as recently as two months ago, the downstream issue (mjs/imapclient#618 languished without maintainer activity. The ideal situation would be a downstream PR that fixes the issues with Python 3.14+ as-is I'm just not sure what that would be. I appreciate the willingness to revert a change upstream though.

  6. seanthegeek commented on Dec 6, 2025

    Author

    @picnixz Those PRs might not be needed if the imapclient merges my PR and publishes a new release.

    mjs/imapclient#629

  7. picnixz commented on Dec 6, 2025

    Member

    Yes but it's better if other users aren't also affected. It's not just one package that may be affected but everyone else. It's also preferrable to entirely remove the attribute in the future if possible.

  8. added a commit that references this issue on Feb 21, 2026
  9. serhiy-storchaka commented on Feb 25, 2026

    Member

    I do not understand how making the file attribute writeable will help the code that sets the file attribute. They do this for purpose, expecting that this will affect the following I/O, If this is a no-op (since this value is not used), they will be broken in more subtle way.

  10. seanthegeek commented on Mar 4, 2026

    Author

    For what it's worth, imappclient did merge my PR and release it, and there is no reason to access the file attribute writeable again.

  11. picnixz commented on Mar 7, 2026

    Member

    So I closed the corresponding PRs. Considering imapclient is the only consumer I could find in the wild, I think it's fine. OTOH, I think we should instead properly deprecate the attribute as it's currently raising a RuntimeWarning. So I'll open another issue and change the refs in the corresponding PR (that way, the discussion here stays for posterity)

  12. added a commit that references this issue on May 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

3.14bugs and security fixes3.15bugs and security fixesstdlibStandard Library Python modules in the Lib/ directorytopic-emailtype-bugAn unexpected behavior, bug, or error

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions


    Back | FazBrowse Home | New Git URL