8000 bpo-34002: Minor efficiency and clarity improvements in email package… · python/cpython@2702638 · GitHub
[go: up one dir, main page]

Skip to content

Commit 2702638

Browse files
selikmaxking
authored andcommitted
bpo-34002: Minor efficiency and clarity improvements in email package. (GH-7999)
* Check intersection of two sets explicitly Comparing ``len(a) > ``len(a - b)`` is essentially looking for an intersection between the two sets. If set ``b`` does not intersect ``a`` then ``len(a - b)`` will be equal to ``len(a)``. This logic is more clearly expressed as ``a & b``. * Change while/pop to a for-loop Copying the list, then repeatedly popping the first element was unnecessarily slow. I also cleaned up a couple other inefficiencies. There's no need to unpack a tuple, then re-pack and append it. The list can be created with the first element instead of empty. Secondly, the ``endswith`` method returns a bool, so there's no need for an if- statement to set ``encoding`` to True or False. * Use set.intersection to check for intersections ``a.intersection(b)`` method is more clear of purpose than ``not a.isdisjoint(b)`` and avoids an unnecessary set construction that ``a & set(b)`` performs. * Use not isdisjoint instead of intersection While it reads slightly worse, the isdisjoint method will stop when it finds a counterexample and returns a bool, rather than looping over the entire iterable and constructing a new set.
1 parent 3368f3c commit 2702638

File tree

3 files changed

+13
-25
lines changed

3 files changed

+13
-25
lines changed

Lib/email/headerregistry.py

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -69,11 +69,9 @@ def addr_spec(self):
6969
"""The addr_spec (username@domain) portion of the address, quoted
7070
according to RFC 5322 rules, but with no Content Transfer Encoding.
7171
"""
72-
nameset = set(self.username)
73-
if len(nameset) > len(nameset-parser.DOT_ATOM_ENDS):
74-
lp = parser.quote_string(self.username)
75-
else:
76-
lp = self.username
72+
lp = self.username
73+
if not parser.DOT_ATOM_ENDS.isdisjoint(lp):
74+
lp = parser.quote_string(lp)
7775
if self.domain:
7876
return lp + '@' + self.domain
7977
if not lp:
@@ -86,11 +84,9 @@ def __repr__(self):
8684
self.display_name, self.username, self.domain)
8785

8886
def __str__(self):
89-
nameset = set(self.display_name)
90-
if len(nameset) > len(nameset-parser.SPECIALS):
91-
disp = parser.quote_string(self.display_name)
92-
else:
93-
disp = self.display_name
87+
disp = self.display_name
88+
if not parser.SPECIALS.isdisjoint(disp):
89+
disp = parser.quote_string(disp)
9490
if disp:
9591
addr_spec = '' if self.addr_spec=='<>' else self.addr_spec
9692
return "{} <{}>".format(disp, addr_spec)
@@ -141,10 +137,8 @@ def __str__(self):
141137
if self.display_name is None and len(self.addresses)==1:
142138
return str(self.addresses[0])
143139
disp = self.display_name
144-
if disp is not None:
145-
nameset = set(disp)
146-
if len(nameset) > len(nameset-parser.SPECIALS):
147-
disp = parser.quote_string(disp)
140+
if disp is not None and not parser.SPECIALS.isdisjoint(disp):
141+
disp = parser.quote_string(disp)
148142
adrstr = ", ".join(str(x) for x in self.addresses)
149143
adrstr = ' ' + adrstr if adrstr else adrstr
150144
return "{}:{};".format(disp, adrstr)

Lib/email/utils.py

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -259,21 +259,13 @@ def decode_params(params):
259259
260260
params is a sequence of 2-tuples containing (param name, string value).
261261
"""
262-
# Copy params so we don't mess with the original
263-
params = params[:]
264-
new_params = []
262+
new_params = [params[0]]
265263
# Map parameter's name to a list of continuations. The values are a
266264
# 3-tuple of the continuation number, the string value, and a flag
267265
# specifying whether a particular segment is %-encoded.
268266
rfc2231_params = {}
269-
name, value = params.pop(0)
270-
new_params.append((name, value))
271-
while params:
272-
name, value = params.pop(0)
273-
if name.endswith('*'):
274-
encoded = True
275-
else:
276-
encoded = False
267+
for name, value in params[1:]:
268+
encoded = name.endswith('*')
277269
value = unquote(value)
278270
mo = rfc2231_continuation.match(name)
279271
if mo:
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Improve efficiency in parts of email package by changing while-pop to a for
2+
loop, using isdisjoint instead of set intersections.

0 commit comments

Comments
 (0)
0