This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: smtplib throws exception TypeError: readline()
Type: behavior Stage: resolved
Components: email Versions: Python 3.2
process
Status: closed Resolution: out of date
Dependencies: Superseder:
Assigned To: Nosy List: barry, pdonis, phlambotte, r.david.murray
Priority: normal Keywords:

Created on 2015-09-09 15:39 by phlambotte, last changed 2022-04-11 14:58 by admin. This issue is now closed.

Messages (7)
msg250317 - (view) Author: Philippe Lambotte (phlambotte) Date: 2015-09-09 15:39
smtplib  smtpserver.ehlo() will throw exception.
The error message : 
Traceback (most recent call last):
  File "snippet.email.sendmail.py", line 34, in <module>
    smtpserver.ehlo()
  File "/usr/lib/python3.2/smtplib.py", line 421, in ehlo
    (code, msg) = self.getreply()
  File "/usr/lib/python3.2/smtplib.py", line 367, in getreply
    line = self.file.readline(_MAXLINE + 1)
TypeError: readline() takes exactly 1 positional argument (2 given)

smtplib works with python 2.7, but not  with 3.2

If I remove the passed parameter, it works in 3.2 :
     line = self.file.readline()
msg250325 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2015-09-09 17:00
Can you explain how to reproduce the problem? That code is working fine in the unit tests, and the file object returned by socket.makefile has a readline method that accepts a size argument, so I'm guessing there is something odd going on with your code.
msg250327 - (view) Author: Philippe Lambotte (phlambotte) Date: 2015-09-09 18:04
The code is :

#!/usr/bin/env python3
#-*- coding: utf-8 -*-

import smtplib, os
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email.mime.text import MIMEText
from email.utils import COMMASPACE, formatdate
from email import encoders

EMAIL_FROM = 'emailfrom@mywebsite.net'
EMAIL_TO = ['emailto@mywebsite.net']

SENDER_LOGIN = 'mylogin'
SENDER_PASSWORD = 'mypassword'
SMTP_HOST = 'smtp.myhoster.net'
SMTP_PORT = 587
SMTP_IS_STARTTLS = True
SUBJECT ="This is the subject"
TEXT = 'This is a test'
FILES = list() # ['dummy_text.txt']


def send_mail_with_attachment( send_from, send_to, subject, text, files=[], server="localhost", port=587, username='', password='', isTls=True):
	msg = MIMEMultipart()
	msg['From'] = send_from
	msg['To'] = COMMASPACE.join(send_to)
	msg['Date'] = formatdate(localtime = True)
	msg['Subject'] = subject

	msg.attach( MIMEText(text) )
	if len(files) > 0 :
		for f in files:
			part = MIMEBase('application', "octet-stream")
			part.set_payload( open(f,"rb").read() )
			encoders.encode_base64(part)
			part.add_header('Content-Disposition', 'attachment; filename="{0}"'.format(os.path.basename(f)))
			msg.attach(part)

	smtp = smtplib.SMTP(server, port)
	if isTls: smtp.starttls()
	smtp.login(username,password)
	smtp.sendmail(send_from, send_to, msg.as_string())
	smtp.quit()

send_mail_with_attachment(EMAIL_FROM,EMAIL_TO,SUBJECT,TEXT,FILES,SMTP_HOST,SMTP_PORT,SENDER_LOGIN,SENDER_PASSWORD,SMTP_IS_STARTTLS)



When I run it, I have the following message :

Traceback (most recent call last):
  File "snippet.email.envoyer_un_mail_au_format_html.py", line 46, in <module>
    send_mail_with_attachment(EMAIL_FROM,EMAIL_TO,SUBJECT,TEXT,FILES,SMTP_HOST,SMTP_PORT,SENDER_LOGIN,SENDER_PASSWORD,SMTP_IS_STARTTLS)
  File "snippet.email.envoyer_un_mail_au_format_html.py", line 42, in send_mail_with_attachment
    smtp.login(username,password)
  File "/usr/lib/python3.2/smtplib.py", line 595, in login
    self.ehlo_or_helo_if_needed()
  File "/usr/lib/python3.2/smtplib.py", line 554, in ehlo_or_helo_if_needed
    if not (200 <= self.ehlo()[0] <= 299):
  File "/usr/lib/python3.2/smtplib.py", line 421, in ehlo
    (code, msg) = self.getreply()
  File "/usr/lib/python3.2/smtplib.py", line 367, in getreply
    line = self.file.readline(_MAXLINE + 1)
TypeError: readline() takes exactly 1 positional argument (2 given)
msg252499 - (view) Author: Peter Donis (pdonis) * Date: 2015-10-08 01:41
I am having the same problem; the error occurs in the call to the login method of the smtplib.SMTP object. That method takes two arguments, username and password, and that is what I am calling it with.
msg252501 - (view) Author: Peter Donis (pdonis) * Date: 2015-10-08 01:50
Investigating further, the problem appears to be with the SSLFakeFile object used for SSL/TLS connections. Here is a console session showing the issue (I have redacted the host name and port number used for privacy reasons):

>>> import smtplib
>>> smtp = smtplib.SMTP(hostname, portnum)
>>> smtp.file
<_io.BufferedReader name=3>
>>> smtp.starttls()
(220, b'2.0.0 Ready to start TLS')
>>> smtp.file
<smtplib.SSLFakeFile object at 0x1cdb3d0>
>>> smtp.file.readline(1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: readline() takes exactly 1 positional argument (2 given)
msg252502 - (view) Author: Peter Donis (pdonis) * Date: 2015-10-08 01:59
It looks like this was fixed some time in between my Python 3.2 version (3.2.3) and the current one (3.2.6); the code in the current 3.2 head in the repository has a size parameter in the readline function for SSLFakeFile:

https://hg.python.org/cpython/file/3.2/Lib/smtplib.py
msg252503 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2015-10-08 02:08
Thanks for figuring out the cause and that it has already been fixed.
History
Date User Action Args
2022-04-11 14:58:20adminsetgithub: 69233
2015-10-08 02:08:11r.david.murraysetstatus: open -> closed
resolution: out of date
messages: + msg252503

stage: resolved
2015-10-08 01:59:04pdonissetmessages: + msg252502
2015-10-08 01:50:32pdonissetmessages: + msg252501
2015-10-08 01:41:10pdonissetnosy: + pdonis
messages: + msg252499
2015-09-09 18:04:52phlambottesetmessages: + msg250327
2015-09-09 17:00:39r.david.murraysetmessages: + msg250325
2015-09-09 15:39:19phlambottecreate