Repository navigation
imaplib 3.14 regression: IMAP4.file became read-only property, breaking subclass overrides (affects imapclient IMAP4_TLS) #142307
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._filewith 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:
- Add a setter to the property that writes to
_file - Or rename the internal attribute (e.g., _imaplib_file) instead of shadowing a long-existing public attribute name
- Or provide an explicit API for replacing the buffered input stream
- 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, includingmailsuiteandparsedmarc - 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
Activity
1.10.1
9.0.3
Remove Python 3.14 from testing
picnixz commentedon Dec 6, 2025
So I've been trying various approaches and there are few issues:
shutdown()which callsself.file.close(). So if we renamed the attribute, it would becomeself._imaplib_file.close()and the file created by imapclient would still be opened.I'm inclined to actually not change anything and ask maintainers of
imapclientto 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.As per PEP-8, it's not a public attribute. Something that is not documented is not considered part of the public API.
The compatibility was never really supported because of the previous file not being closed.
pythongh-142307: restore legacy support for altering ``IMAP4.file``
pythongh-142307: restore legacy support for altering ``IMAP4.file``
seanthegeek commentedon Dec 6, 2025
As I read through this whole situation more, yeah. It should really be on the maintainers of
imapclientto use an approach that does not usefilefor 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.seanthegeek commentedon Dec 6, 2025
@picnixz Those PRs might not be needed if the imapclient merges my PR and publishes a new release.
mjs/imapclient#629
picnixz commentedon Dec 6, 2025
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.
9.0.3
Remove Python 3.14 from testing
pythongh-142307: restore legacy support for altering ``IMAP4.file``
serhiy-storchaka commentedon Feb 25, 2026
I do not understand how making the
fileattribute writeable will help the code that sets thefileattribute. 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.seanthegeek commentedon Mar 4, 2026
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.
picnixz commentedon Mar 7, 2026
So I closed the corresponding PRs. Considering
imapclientis 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)gh-142307: deprecate legacy support for altering `IMAP4.file` (#142335)