mirror of
				https://github.com/django/django.git
				synced 2025-10-31 01:25:32 +00:00 
			
		
		
		
	- Changed EmailMessage.message() to construct a "modern email API" email.message.EmailMessage and added policy keyword arg. - Added support for modern MIMEPart objects in EmailMessage.attach() (and EmailMessage constructor, EmailMessage.attachments list). - Updated SMTP EmailBackend to use modern email.policy.SMTP. Deprecated: - Attaching MIMEBase objects (replace with MIMEPart) - BadHeaderError (modern email uses ValueError) - SafeMIMEText, SafeMIMEMultipart (unnecessary for modern email) - django.core.mail.forbid_multi_line_headers() (undocumented, but exposed via `__all__` and in wide use) - django.core.mail.message.sanitize_address() (undocumented, but in wide use) Removed without deprecation (all undocumented): - EmailMessage.mixed_subtype - EmailMultiAlternatives.alternative_subtype - Support for setting (undocumented) EmailMessage.encoding property to a legacy email.charset.Charset object Related changes: - Dropped tests for incorrect RFC 2047 encoding of non-ASCII email address localparts. This is specifically prohibited by RFC 2047, and not supported by any known MTA or email client. (Python still mis-applies encoded-word to non-ASCII localparts, but it is a bug that may be fixed in the future.) - Added tests that try to discourage using Python's legacy email APIs in future updates to django.core.mail.
		
			
				
	
	
		
			123 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			123 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| # RemovedInDjango70Warning: This entire file.
 | |
| from email.mime.text import MIMEText
 | |
| 
 | |
| from django.core.mail import (
 | |
|     EmailAlternative,
 | |
|     EmailAttachment,
 | |
|     EmailMessage,
 | |
|     EmailMultiAlternatives,
 | |
| )
 | |
| from django.core.mail.message import forbid_multi_line_headers, sanitize_address
 | |
| from django.test import SimpleTestCase, ignore_warnings
 | |
| from django.utils.deprecation import RemovedInDjango70Warning
 | |
| 
 | |
| from .tests import MailTestsMixin
 | |
| 
 | |
| 
 | |
| class DeprecationWarningTests(MailTestsMixin, SimpleTestCase):
 | |
|     def test_deprecated_on_import(self):
 | |
|         """
 | |
|         These items are not typically called from user code,
 | |
|         so generate deprecation warnings immediately at the time
 | |
|         they are imported from django.core.mail.
 | |
|         """
 | |
|         cases = [
 | |
|             # name, msg
 | |
|             (
 | |
|                 "BadHeaderError",
 | |
|                 "BadHeaderError is deprecated. Replace with ValueError.",
 | |
|             ),
 | |
|             (
 | |
|                 "SafeMIMEText",
 | |
|                 "SafeMIMEText is deprecated. The return value of"
 | |
|                 " EmailMessage.message() is an email.message.EmailMessage.",
 | |
|             ),
 | |
|             (
 | |
|                 "SafeMIMEMultipart",
 | |
|                 "SafeMIMEMultipart is deprecated. The return value of"
 | |
|                 " EmailMessage.message() is an email.message.EmailMessage.",
 | |
|             ),
 | |
|         ]
 | |
|         for name, msg in cases:
 | |
|             with self.subTest(name=name):
 | |
|                 with self.assertWarnsMessage(RemovedInDjango70Warning, msg):
 | |
|                     __import__("django.core.mail", fromlist=[name])
 | |
| 
 | |
|     def test_sanitize_address_deprecated(self):
 | |
|         msg = (
 | |
|             "The internal API sanitize_address() is deprecated."
 | |
|             " Python's modern email API (with email.message.EmailMessage or"
 | |
|             " email.policy.default) will handle most required validation and"
 | |
|             " encoding. Use Python's email.headerregistry.Address to construct"
 | |
|             " formatted addresses from component parts."
 | |
|         )
 | |
|         with self.assertWarnsMessage(RemovedInDjango70Warning, msg):
 | |
|             sanitize_address("to@example.com", "ascii")
 | |
| 
 | |
|     def test_forbid_multi_line_headers_deprecated(self):
 | |
|         msg = (
 | |
|             "The internal API forbid_multi_line_headers() is deprecated."
 | |
|             " Python's modern email API (with email.message.EmailMessage or"
 | |
|             " email.policy.default) will reject multi-line headers."
 | |
|         )
 | |
|         with self.assertWarnsMessage(RemovedInDjango70Warning, msg):
 | |
|             forbid_multi_line_headers("To", "to@example.com", "ascii")
 | |
| 
 | |
| 
 | |
| class UndocumentedFeatureErrorTests(SimpleTestCase):
 | |
|     """
 | |
|     These undocumented features were removed without going through deprecation.
 | |
|     In case they were being used, they now raise errors.
 | |
|     """
 | |
| 
 | |
|     def test_undocumented_mixed_subtype(self):
 | |
|         """
 | |
|         Trying to use the previously undocumented, now unsupported
 | |
|         EmailMessage.mixed_subtype causes an error.
 | |
|         """
 | |
|         msg = (
 | |
|             "EmailMessage no longer supports"
 | |
|             " the undocumented `mixed_subtype` attribute"
 | |
|         )
 | |
|         email = EmailMessage(
 | |
|             attachments=[EmailAttachment(None, b"GIF89a...", "image/gif")]
 | |
|         )
 | |
|         email.mixed_subtype = "related"
 | |
|         with self.assertRaisesMessage(AttributeError, msg):
 | |
|             email.message()
 | |
| 
 | |
|     def test_undocumented_alternative_subtype(self):
 | |
|         """
 | |
|         Trying to use the previously undocumented, now unsupported
 | |
|         EmailMultiAlternatives.alternative_subtype causes an error.
 | |
|         """
 | |
|         msg = (
 | |
|             "EmailMultiAlternatives no longer supports"
 | |
|             " the undocumented `alternative_subtype` attribute"
 | |
|         )
 | |
|         email = EmailMultiAlternatives(
 | |
|             alternatives=[EmailAlternative("", "text/plain")]
 | |
|         )
 | |
|         email.alternative_subtype = "multilingual"
 | |
|         with self.assertRaisesMessage(AttributeError, msg):
 | |
|             email.message()
 | |
| 
 | |
| 
 | |
| @ignore_warnings(category=RemovedInDjango70Warning)
 | |
| class DeprecatedCompatibilityTests(SimpleTestCase):
 | |
|     def test_bad_header_error(self):
 | |
|         """
 | |
|         Existing code that catches deprecated BadHeaderError should be
 | |
|         compatible with modern email (which raises ValueError instead).
 | |
|         """
 | |
|         from django.core.mail import BadHeaderError
 | |
| 
 | |
|         with self.assertRaises(BadHeaderError):
 | |
|             EmailMessage(subject="Bad\r\nHeader").message()
 | |
| 
 | |
|     def test_attachments_mimebase_in_constructor(self):
 | |
|         txt = MIMEText("content1")
 | |
|         msg = EmailMessage(attachments=[txt])
 | |
|         payload = msg.message().get_payload()
 | |
|         self.assertEqual(payload[0], txt)
 |