smtp = smtplib.SMTP(HOST, self.port, local_hostname='localhost', timeout=15)
try: smtp.login(sim_auth[0], sim_auth[1])
except smtplib.SMTPAuthenticationError as err:
- self.assertIn(sim_auth_login_password, str(err))
+ self.assertIn(sim_auth_login_user, str(err))
+ smtp.close()
+
+ def test_auth_function(self):
+ smtp = smtplib.SMTP(HOST, self.port,
+ local_hostname='localhost', timeout=15)
+ self.serv.add_feature("AUTH CRAM-MD5")
+ smtp.user, smtp.password = sim_auth[0], sim_auth[1]
+ supported = {'CRAM-MD5': smtp.auth_cram_md5,
+ 'PLAIN': smtp.auth_plain,
+ 'LOGIN': smtp.auth_login,
+ }
+ for mechanism, method in supported.items():
+ try: smtp.auth(mechanism, method)
+ except smtplib.SMTPAuthenticationError as err:
+ self.assertIn(sim_auth_credentials[mechanism.lower()].upper(),
+ str(err))
smtp.close()
+ def test_quit_resets_greeting(self):
+ smtp = smtplib.SMTP(HOST, self.port,
+ local_hostname='localhost',
+ timeout=15)
+ code, message = smtp.ehlo()
+ self.assertEqual(code, 250)
+ self.assertIn('size', smtp.esmtp_features)
+ smtp.quit()
+ self.assertNotIn('size', smtp.esmtp_features)
+ smtp.connect(HOST, self.port)
+ self.assertNotIn('size', smtp.esmtp_features)
+ smtp.ehlo_or_helo_if_needed()
+ self.assertIn('size', smtp.esmtp_features)
+ smtp.quit()
+
def test_with_statement(self):
with smtplib.SMTP(HOST, self.port) as smtp:
code, message = smtp.noop()
Library
-------
+ - Issue #22216: smtplib now resets its state more completely after a quit. The
+ most obvious consequence of the previous behavior was a STARTTLS failure
+ during a connect/starttls/quit/connect/starttls sequence.
+
+- Issue #22098: ctypes' BigEndianStructure and LittleEndianStructure now
+ define an empty __slots__ so that subclasses don't always get an instance
+ dict. Patch by Claudiu Popa.
+
- Issue #22185: Fix an occasional RuntimeError in threading.Condition.wait()
caused by mutation of the waiters queue without holding the lock. Patch
by Doug Zongker.