Pergunta
Eu tenho um pedaço muito simples de código que eu usei em versões anteriores do Python sem problemas (versão 2.5 e anteriores). Agora com 3.0, o código a seguir dá o erro na linha de login "argumento 1 deve ser string ou tampão, não str".
import smtplib
smtpserver = 'mail.somedomain.com'
AUTHREQUIRED = 1 # if you need to use SMTP AUTH set to 1
smtpuser = 'admin@somedomain.com' # for SMTP AUTH, set SMTP username here
smtppass = 'somepassword' # for SMTP AUTH, set SMTP password here
msg = "Some message to send"
RECIPIENTS = ['admin@somedomain.com']
SENDER = 'someone@someotherdomain.net'
session = smtplib.SMTP(smtpserver)
if AUTHREQUIRED:
session.login(smtpuser, smtppass)
smtpresult = session.sendmail(SENDER, RECIPIENTS, msg)
Google mostra há algumas questões com que o erro não sendo claro, mas eu ainda não consigo descobrir o que eu preciso para tentar fazê-lo funcionar. Sugestões incluíram a definição do nome de usuário como b "username", mas que não parecem funcionar.
Solução
Atualizar : só notei a partir de um olhar para o bug tracker há uma correção sugerida também:
Editar smtplib.py e substituir a definição encode_plain()
existente com o seguinte:
def encode_plain(user, password):
s = "\0%s\0%s" % (user, password)
return encode_base64(s.encode('ascii'), eol='')
Testado aqui na minha instalação e funciona corretamente.
Outras dicas
Traceback (most recent call last):
File "smtptest.py", line 18, in <module>
session.login(smtpuser, smtppass)
File "c:\Python30\lib\smtplib.py", line 580, in login
AUTH_PLAIN + " " + encode_plain(user, password))
File "c:\Python30\lib\smtplib.py", line 545, in encode_plain
return encode_base64("\0%s\0%s" % (user, password))
File "c:\Python30\lib\email\base64mime.py", line 96, in body_encode
enc = b2a_base64(s[i:i + max_unencoded]).decode("ascii")
TypeError: b2a_base64() argument 1 must be bytes or buffer, not str
O código está correto. Este é um erro no smtplib ou base64mime.py . Você pode acompanhar a questão aqui: http://bugs.python.org/issue5259
Esperamos que os devs irá publicar uma correção em breve.
Como uma variação na resposta de Jay, em vez de editar smtplib.py você poderia "monkey patch"-lo em tempo de execução.
Coloque isso em algum lugar em seu código:
def encode_plain(user, password):
s = "\0%s\0%s" % (user, password)
return encode_base64(s.encode('ascii'), eol='')
import smtplib
encode_plain.func_globals = vars(smtplib)
smtplib.encode_plain = encode_plain
Este é tipo de feio, mas útil se você deseja implantar seu código em outros sistemas sem fazer alterações às suas bibliotecas python.
Esta questão foi abordada na Python3.1. Obter a atualização em http://www.python.org/download/releases/3.1/