Skip to content

Commit 2e59b79

Browse files
Merge branch 'main' into long-from-dev_t
2 parents 90525d0 + 48c907a commit 2e59b79

17 files changed

+3975
-3904
lines changed

Doc/library/itertools.rst

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -164,11 +164,14 @@ loops that truncate the stream.
164164
Added the optional *initial* parameter.
165165

166166

167-
.. function:: batched(iterable, n)
167+
.. function:: batched(iterable, n, *, strict=False)
168168

169169
Batch data from the *iterable* into tuples of length *n*. The last
170170
batch may be shorter than *n*.
171171

172+
If *strict* is true, will raise a :exc:`ValueError` if the final
173+
batch is shorter than *n*.
174+
172175
Loops over the input iterable and accumulates data into tuples up to
173176
size *n*. The input is consumed lazily, just enough to fill a batch.
174177
The result is yielded as soon as the batch is full or when the input
@@ -190,16 +193,21 @@ loops that truncate the stream.
190193

191194
Roughly equivalent to::
192195

193-
def batched(iterable, n):
196+
def batched(iterable, n, *, strict=False):
194197
# batched('ABCDEFG', 3) --> ABC DEF G
195198
if n < 1:
196199
raise ValueError('n must be at least one')
197200
it = iter(iterable)
198201
while batch := tuple(islice(it, n)):
202+
if strict and len(batch) != n:
203+
raise ValueError('batched(): incomplete batch')
199204
yield batch
200205

201206
.. versionadded:: 3.12
202207

208+
.. versionchanged:: 3.13
209+
Added the *strict* option.
210+
203211

204212
.. function:: chain(*iterables)
205213

@@ -1039,7 +1047,7 @@ The following recipes have a more mathematical flavor:
10391047
def reshape(matrix, cols):
10401048
"Reshape a 2-D matrix to have a given number of columns."
10411049
# reshape([(0, 1), (2, 3), (4, 5)], 3) --> (0, 1, 2), (3, 4, 5)
1042-
return batched(chain.from_iterable(matrix), cols)
1050+
return batched(chain.from_iterable(matrix), cols, strict=True)
10431051

10441052
def transpose(matrix):
10451053
"Swap the rows and columns of a 2-D matrix."
@@ -1270,6 +1278,10 @@ The following recipes have a more mathematical flavor:
12701278
[(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, 10, 11)]
12711279
>>> list(reshape(M, 4))
12721280
[(0, 1, 2, 3), (4, 5, 6, 7), (8, 9, 10, 11)]
1281+
>>> list(reshape(M, 5))
1282+
Traceback (most recent call last):
1283+
...
1284+
ValueError: batched(): incomplete batch
12731285
>>> list(reshape(M, 6))
12741286
[(0, 1, 2, 3, 4, 5), (6, 7, 8, 9, 10, 11)]
12751287
>>> list(reshape(M, 12))

Doc/library/os.rst

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4570,7 +4570,8 @@ written in Python, such as a mail server's external command delivery program.
45704570
Most users should use :func:`subprocess.run` instead of :func:`posix_spawn`.
45714571

45724572
The positional-only arguments *path*, *args*, and *env* are similar to
4573-
:func:`execve`.
4573+
:func:`execve`. *env* is allowed to be ``None``, in which case current
4574+
process' environment is used.
45744575

45754576
The *path* parameter is the path to the executable file. The *path* should
45764577
contain a directory. Use :func:`posix_spawnp` to pass an executable file
@@ -4645,6 +4646,9 @@ written in Python, such as a mail server's external command delivery program.
46454646

46464647
.. versionadded:: 3.8
46474648

4649+
.. versionchanged:: 3.13
4650+
*env* parameter accepts ``None``.
4651+
46484652
.. availability:: Unix, not Emscripten, not WASI.
46494653

46504654
.. function:: posix_spawnp(path, argv, env, *, file_actions=None, \

Doc/whatsnew/3.13.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,10 @@ os
289289
``False`` on Windows.
290290
(Contributed by Serhiy Storchaka in :gh:`59616`)
291291

292+
* :func:`os.posix_spawn` now accepts ``env=None``, which makes the newly spawned
293+
process use the current process environment.
294+
(Contributed by Jakub Kulik in :gh:`113119`.)
295+
292296
pathlib
293297
-------
294298

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
1+
" Example to test recognition of .pyi file as Python source code.
2+
13
class Example:
24
def method(self, argument1: str, argument2: list[int]) -> None: ...

Lib/idlelib/util.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@
1313
* warning stuff (pyshell, run).
1414
"""
1515

16-
# .pyw is for Windows; .pyi is for stub files.
17-
py_extensions = ('.py', '.pyw', '.pyi') # Order needed for open/save dialogs.
18-
16+
# .pyw is for Windows; .pyi is for typing stub files.
17+
# The extension order is needed for iomenu open/save dialogs.
18+
py_extensions = ('.py', '.pyw', '.pyi')
1919

2020
if __name__ == '__main__':
2121
from unittest import main

Lib/subprocess.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1756,9 +1756,6 @@ def _posix_spawn(self, args, executable, env, restore_signals,
17561756
c2pread, c2pwrite,
17571757
errread, errwrite):
17581758
"""Execute program using os.posix_spawn()."""
1759-
if env is None:
1760-
env = os.environ
1761-
17621759
kwargs = {}
17631760
if restore_signals:
17641761
# See _Py_RestoreSignals() in Python/pylifecycle.c

Lib/test/test_itertools.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,11 @@ def test_batched(self):
187187
[('A', 'B'), ('C', 'D'), ('E', 'F'), ('G',)])
188188
self.assertEqual(list(batched('ABCDEFG', 1)),
189189
[('A',), ('B',), ('C',), ('D',), ('E',), ('F',), ('G',)])
190+
self.assertEqual(list(batched('ABCDEF', 2, strict=True)),
191+
[('A', 'B'), ('C', 'D'), ('E', 'F')])
190192

193+
with self.assertRaises(ValueError): # Incomplete batch when strict
194+
list(batched('ABCDEFG', 3, strict=True))
191195
with self.assertRaises(TypeError): # Too few arguments
192196
list(batched('ABCDEFG'))
193197
with self.assertRaises(TypeError):

0 commit comments

Comments
 (0)