Skip to content

Commit 5914c78

Browse files
authored
Merge branch 'main' into feature/113174-importlib-metadata-7.0
2 parents b610b6d + 4a153a1 commit 5914c78

24 files changed

+892
-585
lines changed

Doc/library/email.utils.rst

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,13 +58,18 @@ of the new API.
5858
begins with angle brackets, they are stripped off.
5959

6060

61-
.. function:: parseaddr(address)
61+
.. function:: parseaddr(address, *, strict=True)
6262

6363
Parse address -- which should be the value of some address-containing field such
6464
as :mailheader:`To` or :mailheader:`Cc` -- into its constituent *realname* and
6565
*email address* parts. Returns a tuple of that information, unless the parse
6666
fails, in which case a 2-tuple of ``('', '')`` is returned.
6767

68+
If *strict* is true, use a strict parser which rejects malformed inputs.
69+
70+
.. versionchanged:: 3.13
71+
Add *strict* optional parameter and reject malformed inputs by default.
72+
6873

6974
.. function:: formataddr(pair, charset='utf-8')
7075

@@ -82,12 +87,15 @@ of the new API.
8287
Added the *charset* option.
8388

8489

85-
.. function:: getaddresses(fieldvalues)
90+
.. function:: getaddresses(fieldvalues, *, strict=True)
8691

8792
This method returns a list of 2-tuples of the form returned by ``parseaddr()``.
8893
*fieldvalues* is a sequence of header field values as might be returned by
89-
:meth:`Message.get_all <email.message.Message.get_all>`. Here's a simple
90-
example that gets all the recipients of a message::
94+
:meth:`Message.get_all <email.message.Message.get_all>`.
95+
96+
If *strict* is true, use a strict parser which rejects malformed inputs.
97+
98+
Here's a simple example that gets all the recipients of a message::
9199

92100
from email.utils import getaddresses
93101

@@ -97,6 +105,9 @@ of the new API.
97105
resent_ccs = msg.get_all('resent-cc', [])
98106
all_recipients = getaddresses(tos + ccs + resent_tos + resent_ccs)
99107

108+
.. versionchanged:: 3.13
109+
Add *strict* optional parameter and reject malformed inputs by default.
110+
100111

101112
.. function:: parsedate(date)
102113

Doc/library/itertools.rst

Lines changed: 34 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1017,6 +1017,8 @@ which incur interpreter overhead.
10171017
"List unique elements, preserving order. Remember only the element just seen."
10181018
# unique_justseen('AAAABBBCCDAABBB') --> A B C D A B
10191019
# unique_justseen('ABBcCAD', str.lower) --> A B c A D
1020+
if key is None:
1021+
return map(operator.itemgetter(0), groupby(iterable))
10201022
return map(next, map(operator.itemgetter(1), groupby(iterable, key)))
10211023

10221024

@@ -1136,24 +1138,6 @@ The following recipes have a more mathematical flavor:
11361138
n = n // p * (p - 1)
11371139
return n
11381140

1139-
def nth_combination(iterable, r, index):
1140-
"Equivalent to list(combinations(iterable, r))[index]"
1141-
pool = tuple(iterable)
1142-
n = len(pool)
1143-
c = math.comb(n, r)
1144-
if index < 0:
1145-
index += c
1146-
if index < 0 or index >= c:
1147-
raise IndexError
1148-
result = []
1149-
while r:
1150-
c, n, r = c*r//n, n-1, r-1
1151-
while index >= c:
1152-
index -= c
1153-
c, n = c*(n-r)//n, n-1
1154-
result.append(pool[-1-n])
1155-
return tuple(result)
1156-
11571141

11581142
.. doctest::
11591143
:hide:
@@ -1577,20 +1561,6 @@ The following recipes have a more mathematical flavor:
15771561
>>> first_true('ABC0DEF1', '9', str.isdigit)
15781562
'0'
15791563

1580-
>>> population = 'ABCDEFGH'
1581-
>>> for r in range(len(population) + 1):
1582-
... seq = list(combinations(population, r))
1583-
... for i in range(len(seq)):
1584-
... assert nth_combination(population, r, i) == seq[i]
1585-
... for i in range(-len(seq), 0):
1586-
... assert nth_combination(population, r, i) == seq[i]
1587-
1588-
>>> iterable = 'abcde'
1589-
>>> r = 3
1590-
>>> combos = list(combinations(iterable, r))
1591-
>>> all(nth_combination(iterable, r, i) == comb for i, comb in enumerate(combos))
1592-
True
1593-
15941564

15951565
.. testcode::
15961566
:hide:
@@ -1617,6 +1587,24 @@ The following recipes have a more mathematical flavor:
16171587
for (a, _), (b, c) in pairwise(pairwise(iterable)):
16181588
yield a, b, c
16191589

1590+
def nth_combination(iterable, r, index):
1591+
"Equivalent to list(combinations(iterable, r))[index]"
1592+
pool = tuple(iterable)
1593+
n = len(pool)
1594+
c = math.comb(n, r)
1595+
if index < 0:
1596+
index += c
1597+
if index < 0 or index >= c:
1598+
raise IndexError
1599+
result = []
1600+
while r:
1601+
c, n, r = c*r//n, n-1, r-1
1602+
while index >= c:
1603+
index -= c
1604+
c, n = c*(n-r)//n, n-1
1605+
result.append(pool[-1-n])
1606+
return tuple(result)
1607+
16201608

16211609
.. doctest::
16221610
:hide:
@@ -1632,3 +1620,17 @@ The following recipes have a more mathematical flavor:
16321620

16331621
>>> list(triplewise('ABCDEFG'))
16341622
[('A', 'B', 'C'), ('B', 'C', 'D'), ('C', 'D', 'E'), ('D', 'E', 'F'), ('E', 'F', 'G')]
1623+
1624+
>>> population = 'ABCDEFGH'
1625+
>>> for r in range(len(population) + 1):
1626+
... seq = list(combinations(population, r))
1627+
... for i in range(len(seq)):
1628+
... assert nth_combination(population, r, i) == seq[i]
1629+
... for i in range(-len(seq), 0):
1630+
... assert nth_combination(population, r, i) == seq[i]
1631+
1632+
>>> iterable = 'abcde'
1633+
>>> r = 3
1634+
>>> combos = list(combinations(iterable, r))
1635+
>>> all(nth_combination(iterable, r, i) == comb for i, comb in enumerate(combos))
1636+
True

0 commit comments

Comments
 (0)