Skip to content

Commit 9acf650

Browse files
committed
Utils: Finish ParsedEmail --> EmailAddress conversion
Within an EmailAddress (previously ParsedEmail object), properties now match Python 3.6 email.headerregistry.Address naming: * .email --> .addr_spec * .name --> .display_name * .localpart --> .username (Completes work started in 3866689; this updates remaining uses of old names and removes them.)
1 parent bb68f3d commit 9acf650

File tree

10 files changed

+40
-56
lines changed

10 files changed

+40
-56
lines changed

anymail/backends/mailgun.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ def parse_recipient_status(self, response, payload, message):
5353
backend=self)
5454
# Simulate a per-recipient status of "queued":
5555
status = AnymailRecipientStatus(message_id=message_id, status="queued")
56-
return {recipient.email: status for recipient in payload.all_recipients}
56+
return {recipient.addr_spec: status for recipient in payload.all_recipients}
5757

5858

5959
class MailgunPayload(RequestsPayload):
@@ -127,7 +127,7 @@ def set_recipients(self, recipient_type, emails):
127127
self.data[recipient_type] = [email.address for email in emails]
128128
self.all_recipients += emails # used for backend.parse_recipient_status
129129
if recipient_type == 'to':
130-
self.to_emails = [email.email for email in emails] # used for populate_recipient_variables
130+
self.to_emails = [email.addr_spec for email in emails] # used for populate_recipient_variables
131131

132132
def set_subject(self, subject):
133133
self.data["subject"] = subject

anymail/backends/mailjet.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,8 @@ def parse_recipient_status(self, response, payload, message):
6565
# (Mailjet only communicates "Sent")
6666
for recipients in payload.recipients.values():
6767
for email in recipients:
68-
if email.email not in recipient_status:
69-
recipient_status[email.email] = AnymailRecipientStatus(message_id=None, status='unknown')
68+
if email.addr_spec not in recipient_status:
69+
recipient_status[email.addr_spec] = AnymailRecipientStatus(message_id=None, status='unknown')
7070

7171
return recipient_status
7272

@@ -144,9 +144,9 @@ def _finish_recipients_with_vars(self):
144144
merge_data = self.merge_data or {}
145145
for email in self.recipients["to"]:
146146
recipient = {
147-
"Email": email.email,
148-
"Name": email.name,
149-
"Vars": merge_data.get(email.email)
147+
"Email": email.addr_spec,
148+
"Name": email.display_name,
149+
"Vars": merge_data.get(email.addr_spec)
150150
}
151151
# Strip out empty Name and Vars
152152
recipient = {k: v for k, v in recipient.items() if v}
@@ -163,9 +163,9 @@ def _finish_recipients_single(self):
163163
# Workaround Mailjet 3.0 bug parsing display-name with commas
164164
# (see test_comma_in_display_name in test_mailjet_backend for details)
165165
formatted_emails = [
166-
email.address if "," not in email.name
166+
email.address if "," not in email.display_name
167167
# else name has a comma, so force it into MIME encoded-word utf-8 syntax:
168-
else EmailAddress(email.name.encode('utf-8'), email.email).formataddr('utf-8')
168+
else EmailAddress(email.display_name.encode('utf-8'), email.addr_spec).formataddr('utf-8')
169169
for email in emails
170170
]
171171
self.data[recipient_type.capitalize()] = ", ".join(formatted_emails)
@@ -175,9 +175,9 @@ def init_payload(self):
175175
}
176176

177177
def set_from_email(self, email):
178-
self.data["FromEmail"] = email.email
179-
if email.name:
180-
self.data["FromName"] = email.name
178+
self.data["FromEmail"] = email.addr_spec
179+
if email.display_name:
180+
self.data["FromName"] = email.display_name
181181

182182
def set_recipients(self, recipient_type, emails):
183183
assert recipient_type in ["to", "cc", "bcc"]

anymail/backends/mandrill.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -95,14 +95,14 @@ def set_from_email(self, email):
9595
if getattr(self.message, "use_template_from", False):
9696
self.deprecation_warning('message.use_template_from', 'message.from_email = None')
9797
else:
98-
self.data["message"]["from_email"] = email.email
99-
if email.name:
100-
self.data["message"]["from_name"] = email.name
98+
self.data["message"]["from_email"] = email.addr_spec
99+
if email.display_name:
100+
self.data["message"]["from_name"] = email.display_name
101101

102102
def add_recipient(self, recipient_type, email):
103103
assert recipient_type in ["to", "cc", "bcc"]
104104
to_list = self.data["message"].setdefault("to", [])
105-
to_list.append({"email": email.email, "name": email.name, "type": recipient_type})
105+
to_list.append({"email": email.addr_spec, "name": email.display_name, "type": recipient_type})
106106

107107
def set_subject(self, subject):
108108
if getattr(self.message, "use_template_subject", False):

anymail/backends/postmark.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,9 @@ def parse_recipient_status(self, response, payload, message):
6969
backend=self)
7070

7171
return {
72-
recipient.email: AnymailRecipientStatus(
72+
recipient.addr_spec: AnymailRecipientStatus(
7373
message_id=message_id,
74-
status=('rejected' if recipient.email.lower() in rejected_emails
74+
status=('rejected' if recipient.addr_spec.lower() in rejected_emails
7575
else default_status)
7676
)
7777
for recipient in payload.all_recipients

anymail/backends/sendgrid.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ def parse_recipient_status(self, response, payload, message):
6464
# SendGrid v3 doesn't provide any information in the response for a successful send,
6565
# so simulate a per-recipient status of "queued":
6666
status = AnymailRecipientStatus(message_id=payload.message_id, status="queued")
67-
return {recipient.email: status for recipient in payload.all_recipients}
67+
return {recipient.addr_spec: status for recipient in payload.all_recipients}
6868

6969

7070
class SendGridPayload(RequestsPayload):
@@ -199,17 +199,17 @@ def build_merge_data(self):
199199

200200
@staticmethod
201201
def email_object(email, workaround_name_quote_bug=False):
202-
"""Converts ParsedEmail to SendGrid API {email, name} dict"""
203-
obj = {"email": email.email}
204-
if email.name:
202+
"""Converts EmailAddress to SendGrid API {email, name} dict"""
203+
obj = {"email": email.addr_spec}
204+
if email.display_name:
205205
# Work around SendGrid API bug: v3 fails to properly quote display-names
206206
# containing commas or semicolons in personalizations (but not in from_email
207207
# or reply_to). See https://github.com/sendgrid/sendgrid-python/issues/291.
208208
# We can work around the problem by quoting the name for SendGrid.
209209
if workaround_name_quote_bug:
210-
obj["name"] = '"%s"' % rfc822_quote(email.name)
210+
obj["name"] = '"%s"' % rfc822_quote(email.display_name)
211211
else:
212-
obj["name"] = email.name
212+
obj["name"] = email.display_name
213213
return obj
214214

215215
def set_from_email(self, email):

anymail/backends/sendgrid_v2.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ def parse_recipient_status(self, response, payload, message):
6363
backend=self)
6464
# Simulate a per-recipient status of "queued":
6565
status = AnymailRecipientStatus(message_id=payload.message_id, status="queued")
66-
return {recipient.email: status for recipient in payload.all_recipients}
66+
return {recipient.addr_spec: status for recipient in payload.all_recipients}
6767

6868

6969
class SendGridPayload(RequestsPayload):
@@ -166,7 +166,7 @@ def build_merge_data(self):
166166
all_fields = set()
167167
for recipient_data in self.merge_data.values():
168168
all_fields = all_fields.union(recipient_data.keys())
169-
recipients = [email.email for email in self.to_list]
169+
recipients = [email.addr_spec for email in self.to_list]
170170

171171
if self.merge_field_format is None and all(field.isalnum() for field in all_fields):
172172
warnings.warn(
@@ -203,9 +203,9 @@ def init_payload(self):
203203
self.data['headers'] = CaseInsensitiveDict() # headers keys are case-insensitive
204204

205205
def set_from_email(self, email):
206-
self.data["from"] = email.email
207-
if email.name:
208-
self.data["fromname"] = email.name
206+
self.data["from"] = email.addr_spec
207+
if email.display_name:
208+
self.data["fromname"] = email.display_name
209209

210210
def set_to(self, emails):
211211
self.to_list = emails # track for later use by build_merge_data
@@ -214,9 +214,9 @@ def set_to(self, emails):
214214
def set_recipients(self, recipient_type, emails):
215215
assert recipient_type in ["to", "cc", "bcc"]
216216
if emails:
217-
self.data[recipient_type] = [email.email for email in emails]
217+
self.data[recipient_type] = [email.addr_spec for email in emails]
218218
empty_name = " " # SendGrid API balks on complete empty name fields
219-
self.data[recipient_type + "name"] = [email.name or empty_name for email in emails]
219+
self.data[recipient_type + "name"] = [email.display_name or empty_name for email in emails]
220220
self.all_recipients += emails # used for backend.parse_recipient_status
221221

222222
def set_subject(self, subject):

anymail/backends/sparkpost.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ def parse_recipient_status(self, response, payload, message):
7676
else: # mixed results, or wrong total
7777
status = 'unknown'
7878
recipient_status = AnymailRecipientStatus(message_id=transmission_id, status=status)
79-
return {recipient.email: recipient_status for recipient in payload.all_recipients}
79+
return {recipient.addr_spec: recipient_status for recipient in payload.all_recipients}
8080

8181

8282
class SparkPostPayload(BasePayload):
@@ -92,11 +92,11 @@ def get_api_params(self):
9292
if len(self.merge_data) > 0:
9393
# Build JSON recipient structures
9494
for email in self.to_emails:
95-
rcpt = {'address': {'email': email.email}}
96-
if email.name:
97-
rcpt['address']['name'] = email.name
95+
rcpt = {'address': {'email': email.addr_spec}}
96+
if email.display_name:
97+
rcpt['address']['name'] = email.display_name
9898
try:
99-
rcpt['substitution_data'] = self.merge_data[email.email]
99+
rcpt['substitution_data'] = self.merge_data[email.addr_spec]
100100
except KeyError:
101101
pass # no merge_data or none for this recipient
102102
recipients.append(rcpt)

anymail/backends/test.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,15 +68,15 @@ def set_from_email(self, email):
6868

6969
def set_to(self, emails):
7070
self.params['to'] = emails
71-
self.recipient_emails += [email.email for email in emails]
71+
self.recipient_emails += [email.addr_spec for email in emails]
7272

7373
def set_cc(self, emails):
7474
self.params['cc'] = emails
75-
self.recipient_emails += [email.email for email in emails]
75+
self.recipient_emails += [email.addr_spec for email in emails]
7676

7777
def set_bcc(self, emails):
7878
self.params['bcc'] = emails
79-
self.recipient_emails += [email.email for email in emails]
79+
self.recipient_emails += [email.addr_spec for email in emails]
8080

8181
def set_subject(self, subject):
8282
self.params['subject'] = subject

anymail/utils.py

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -232,22 +232,6 @@ def formataddr(self, encoding=None):
232232
def __str__(self):
233233
return self.address
234234

235-
# Deprecated property names from old ParsedEmail (don't use in new code!)
236-
@property
237-
def name(self):
238-
return self.display_name
239-
240-
@property
241-
def email(self):
242-
return self.addr_spec
243-
244-
@property
245-
def localpart(self):
246-
return self.username
247-
248-
249-
ParsedEmail = EmailAddress # deprecated class name (don't use!)
250-
251235

252236
class Attachment(object):
253237
"""A normalized EmailMessage.attachments item with additional functionality

tests/test_send_signals.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ def handle_pre_send(sender, message, esp_name, **kwargs):
3838
self.message.to = ['[email protected]', '[email protected]']
3939
self.message.send()
4040
params = self.get_send_params()
41-
self.assertEqual([email.email for email in params['to']], # params['to'] is ParsedEmail list
41+
self.assertEqual([email.addr_spec for email in params['to']], # params['to'] is EmailAddress list
4242
4343
self.assertRegex(params['text_body'],
4444
r"If you have received this message in error, ignore it$")

0 commit comments

Comments
 (0)