@@ -316,25 +316,30 @@ def open(self, host='', port=IMAP4_PORT, timeout=None):
316316 self .host = host
317317 self .port = port
318318 self .sock = self ._create_socket (timeout )
319- self ._file = self .sock .makefile ('rb' )
320-
319+ # Since IMAP4 implements its own read() and readline() buffering,
320+ # the '_imaplib_file' attribute is unused. Nonetheless it is kept
321+ # and exposed solely for backward compatibility purposes.
322+ self ._imaplib_file = self .sock .makefile ('rb' )
321323
322324 @property
323325 def file (self ):
324- # The old 'file' attribute is no longer used now that we do our own
325- # read() and readline() buffering, with which it conflicts.
326- # As an undocumented interface, it should never have been accessed by
327- # external code, and therefore does not warrant deprecation.
328- # Nevertheless, we provide this property for now, to avoid suddenly
329- # breaking any code in the wild that might have been using it in a
330- # harmless way.
331- import warnings
332- warnings .warn (
333- 'IMAP4.file is unsupported, can cause errors, and may be removed.' ,
334- RuntimeWarning ,
335- stacklevel = 2 )
336- return self ._file
337-
326+ return self ._imaplib_file
327+
328+ @file .setter
329+ def file (self , value ):
330+ # Ideally, we would want to close the previous file,
331+ # but since we do not know how subclasses will use
332+ # that setter, it is probably better to leave it to
333+ # the caller.
334+ self ._imaplib_file = value
335+
336+ def _close_imaplib_file (self ):
337+ file = self ._imaplib_file
338+ if file is not None :
339+ try :
340+ file .close ()
341+ except OSError :
342+ pass
338343
339344 def read (self , size ):
340345 """Read 'size' bytes from remote."""
@@ -420,7 +425,7 @@ def send(self, data):
420425
421426 def shutdown (self ):
422427 """Close I/O established in "open"."""
423- self ._file . close ()
428+ self ._close_imaplib_file ()
424429 try :
425430 self .sock .shutdown (socket .SHUT_RDWR )
426431 except OSError as exc :
@@ -924,9 +929,10 @@ def starttls(self, ssl_context=None):
924929 ssl_context = ssl ._create_stdlib_context ()
925930 typ , dat = self ._simple_command (name )
926931 if typ == 'OK' :
932+ self ._close_imaplib_file ()
927933 self .sock = ssl_context .wrap_socket (self .sock ,
928934 server_hostname = self .host )
929- self ._file = self .sock .makefile ('rb' )
935+ self ._imaplib_file = self .sock .makefile ('rb' )
930936 self ._tls_established = True
931937 self ._get_capabilities ()
932938 else :
@@ -1681,7 +1687,7 @@ def open(self, host=None, port=None, timeout=None):
16811687 self .host = None # For compatibility with parent class
16821688 self .port = None
16831689 self .sock = None
1684- self ._file = None
1690+ self ._imaplib_file = None
16851691 self .process = subprocess .Popen (self .command ,
16861692 bufsize = DEFAULT_BUFFER_SIZE ,
16871693 stdin = subprocess .PIPE , stdout = subprocess .PIPE ,
0 commit comments