GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

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

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

New issue
Copy link
New issue
Copy link
Closed as not planned
Closed as not planned
imaplib 3.14 regression: IMAP4.file became read-only property, breaking subclass overrides (affects imapclient IMAP4_TLS)#142307
Copy link
Assignees
picnixz
Labels
3.14bugs and security fixesbugs and security fixes3.15bugs and security fixesbugs and security fixesstdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directorytopic-emailtype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error

Description

@seanthegeek
seanthegeek
opened on Dec 5, 2025
Issue body actions

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

  • gh-142307: deprecate legacy support for altering IMAP4.file #142335
  • [3.14] gh-142307: restore legacy support for altering IMAP4.file #142336
  • gh-142307: restore legacy support for altering IMAP4.file #145071
Reacted by Christoph Nocula
Reacted by Jiří Kuneš

Activity

  1. seanthegeek
    added
    type-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
    on Dec 5, 2025
  2. seanthegeek
    added 3 commits that reference this issue on Dec 5, 2025

    1.10.1

    339bea2

    9.0.3

    cdd000e

    Remove Python 3.14 from testing

    4b78684
  3. StanFromIreland
    added
    stdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directory
    topic-email
    on Dec 5, 2025
  4. picnixz
    self-assigned this
    on Dec 6, 2025
  5. picnixz commented on Dec 6, 2025

    @picnixz
    picnixz
    on Dec 6, 2025
    Member
    More actions

    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.

  6. picnixz
    added 2 commits that reference this issue on Dec 6, 2025

    pythongh-142307: restore legacy support for altering ``IMAP4.file``

    f28c0cc

    pythongh-142307: restore legacy support for altering ``IMAP4.file``

    5dcd4f4
  7. picnixz
    added
    3.14bugs and security fixesbugs and security fixes
    3.15bugs and security fixesbugs and security fixes
    on Dec 6, 2025
  8. seanthegeek commented on Dec 6, 2025

    @seanthegeek
    seanthegeek
    on Dec 6, 2025
    Author
    More actions

    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.

  9. seanthegeek commented on Dec 6, 2025

    @seanthegeek
    seanthegeek
    on Dec 6, 2025
    Author
    More actions

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

    mjs/imapclient#629

  10. picnixz commented on Dec 6, 2025

    @picnixz
    picnixz
    on Dec 6, 2025
    Member
    More actions

    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.

  11. AyazP
    added 2 commits that reference this issue on Feb 18, 2026

    9.0.3

    629f6d6

    Remove Python 3.14 from testing

    3691d10
  12. picnixz
    added a commit that references this issue on Feb 21, 2026

    pythongh-142307: restore legacy support for altering ``IMAP4.file``

    42da497
  13. serhiy-storchaka commented on Feb 25, 2026

    @serhiy-storchaka
    serhiy-storchaka
    on Feb 25, 2026
    Member
    More actions

    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.

  14. seanthegeek commented on Mar 4, 2026

    @seanthegeek
    seanthegeek
    on Mar 4, 2026
    Author
    More actions

    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.

    Reacted by Bénédikt Tran
  15. seanthegeek
    closed this as completedon Mar 4, 2026
  16. picnixz commented on Mar 7, 2026

    @picnixz
    picnixz
    on Mar 7, 2026
    Member
    More actions

    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)

  17. picnixz
    closed this as not plannedon Mar 7, 2026
  18. hugovk
    added a commit that references this issue on May 6, 2026

    gh-142307: deprecate legacy support for altering `IMAP4.file` (#142335)

    7b6c248
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

  • @picnixz
    picnixz

Labels

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

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

    You are visitor 01402503 — GeezerVison does not store the pages you look up.
    Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.