Skip to content

Commit f4f0c93

Browse files
committed
Merge remote-tracking branch 'upstream/main' into binary-op
2 parents 5727650 + 2f42f83 commit f4f0c93

17 files changed

Lines changed: 259 additions & 159 deletions

Doc/faq/programming.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1226,13 +1226,13 @@ This converts the list into a set, thereby removing duplicates, and then back
12261226
into a list.
12271227

12281228

1229-
How do you remove multiple items from a list
1230-
--------------------------------------------
1229+
How do you remove multiple items from a list?
1230+
---------------------------------------------
12311231

12321232
As with removing duplicates, explicitly iterating in reverse with a
12331233
delete condition is one possibility. However, it is easier and faster
12341234
to use slice replacement with an implicit or explicit forward iteration.
1235-
Here are three variations.::
1235+
Here are three variations::
12361236

12371237
mylist[:] = filter(keep_function, mylist)
12381238
mylist[:] = (x for x in mylist if keep_condition)

Include/internal/pycore_opcode_metadata.h

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Include/internal/pycore_uop_ids.h

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Include/internal/pycore_uop_metadata.h

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Lib/email/generator.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
NLCRE = re.compile(r'\r\n|\r|\n')
2323
fcre = re.compile(r'^From ', re.MULTILINE)
2424
NEWLINE_WITHOUT_FWSP = re.compile(r'\r\n[^ \t]|\r[^ \n\t]|\n[^ \t]')
25+
NEWLINE_WITHOUT_FWSP_BYTES = re.compile(br'\r\n[^ \t]|\r[^ \n\t]|\n[^ \t]')
2526

2627

2728
class Generator:
@@ -429,7 +430,16 @@ def _write_headers(self, msg):
429430
# This is almost the same as the string version, except for handling
430431
# strings with 8bit bytes.
431432
for h, v in msg.raw_items():
432-
self._fp.write(self.policy.fold_binary(h, v))
433+
folded = self.policy.fold_binary(h, v)
434+
if self.policy.verify_generated_headers:
435+
linesep = self.policy.linesep.encode()
436+
if not folded.endswith(linesep):
437+
raise HeaderWriteError(
438+
f'folded header does not end with {linesep!r}: {folded!r}')
439+
if NEWLINE_WITHOUT_FWSP_BYTES.search(folded.removesuffix(linesep)):
440+
raise HeaderWriteError(
441+
f'folded header contains newline: {folded!r}')
442+
self._fp.write(folded)
433443
# A blank line always separates headers from body
434444
self.write(self._NL)
435445

Lib/test/test_capi/test_opt.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2897,6 +2897,7 @@ def testfunc(n):
28972897
self.assertIn("_POP_TOP_NOP", uops)
28982898
self.assertLessEqual(count_ops(ex, "_POP_TOP"), 2)
28992899

2900+
<<<<<<< HEAD
29002901
def test_binary_op_refcount_elimination(self):
29012902
class CustomAdder:
29022903
def __init__(self, val):
@@ -2917,6 +2918,22 @@ def testfunc(n):
29172918
self.assertIsNotNone(ex)
29182919
uops = get_opnames(ex)
29192920
self.assertIn("_BINARY_OP", uops)
2921+
=======
2922+
def test_binary_op_extend_float_long_add_refcount_elimination(self):
2923+
def testfunc(n):
2924+
a = 1.5
2925+
b = 2
2926+
res = 0.0
2927+
for _ in range(n):
2928+
res = a + b
2929+
return res
2930+
2931+
res, ex = self._run_with_optimizer(testfunc, TIER2_THRESHOLD)
2932+
self.assertEqual(res, 3.5)
2933+
self.assertIsNotNone(ex)
2934+
uops = get_opnames(ex)
2935+
self.assertIn("_BINARY_OP_EXTEND", uops)
2936+
>>>>>>> upstream/main
29202937
self.assertIn("_POP_TOP_NOP", uops)
29212938
self.assertLessEqual(count_ops(ex, "_POP_TOP"), 2)
29222939

Lib/test/test_email/test_generator.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,7 @@ def test_flatten_unicode_linesep(self):
313313
self.assertEqual(s.getvalue(), self.typ(expected))
314314

315315
def test_verify_generated_headers(self):
316-
"""gh-121650: by default the generator prevents header injection"""
316+
# gh-121650: by default the generator prevents header injection
317317
class LiteralHeader(str):
318318
name = 'Header'
319319
def fold(self, **kwargs):
@@ -334,6 +334,8 @@ def fold(self, **kwargs):
334334

335335
with self.assertRaises(email.errors.HeaderWriteError):
336336
message.as_string()
337+
with self.assertRaises(email.errors.HeaderWriteError):
338+
message.as_bytes()
337339

338340

339341
class TestBytesGenerator(TestGeneratorBase, TestEmailBase):

Lib/test/test_email/test_policy.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,7 @@ def test_short_maxlen_error(self):
296296
policy.fold("Subject", subject)
297297

298298
def test_verify_generated_headers(self):
299-
"""Turning protection off allows header injection"""
299+
# Turning protection off allows header injection
300300
policy = email.policy.default.clone(verify_generated_headers=False)
301301
for text in (
302302
'Header: Value\r\nBad: Injection\r\n',
@@ -319,6 +319,10 @@ def fold(self, **kwargs):
319319
message.as_string(),
320320
f"{text}\nBody",
321321
)
322+
self.assertEqual(
323+
message.as_bytes(),
324+
f"{text}\nBody".encode(),
325+
)
322326

323327
# XXX: Need subclassing tests.
324328
# For adding subclassed objects, make sure the usual rules apply (subclass
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Eliminate redundant refcounting from ``BINARY_OP_EXTEND``.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
:mod:`~email.generator.BytesGenerator` will now refuse to serialize (write) headers
2+
that are unsafely folded or delimited; see
3+
:attr:`~email.policy.Policy.verify_generated_headers`. (Contributed by Bas
4+
Bloemsaat and Petr Viktorin in :gh:`121650`).

0 commit comments

Comments
 (0)