Skip to content

Commit 3b819af

Browse files
committed
Merge remote-tracking branch 'upstream/main' into gh-139271
2 parents 71ea00a + 49aaee7 commit 3b819af

21 files changed

+523
-80
lines changed

Doc/library/signal.rst

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,12 @@ The variables defined in the :mod:`signal` module are:
205205

206206
.. availability:: Unix.
207207

208+
.. data:: SIGPROF
209+
210+
Profiling timer expired.
211+
212+
.. availability:: Unix.
213+
208214
.. data:: SIGQUIT
209215

210216
Terminal quit signal.
@@ -215,6 +221,10 @@ The variables defined in the :mod:`signal` module are:
215221

216222
Segmentation fault: invalid memory reference.
217223

224+
.. data:: SIGSTOP
225+
226+
Stop executing (cannot be caught or ignored).
227+
218228
.. data:: SIGSTKFLT
219229

220230
Stack fault on coprocessor. The Linux kernel does not raise this signal: it
@@ -243,6 +253,12 @@ The variables defined in the :mod:`signal` module are:
243253

244254
.. availability:: Unix.
245255

256+
.. data:: SIGVTALRM
257+
258+
Virtual timer expired.
259+
260+
.. availability:: Unix.
261+
246262
.. data:: SIGWINCH
247263

248264
Window resize signal.

Doc/library/zlib.rst

Lines changed: 133 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ earlier than 1.1.3; 1.1.3 has a `security vulnerability <https://zlib.net/zlib_f
1616

1717
zlib's functions have many options and often need to be used in a particular
1818
order. This documentation doesn't attempt to cover all of the permutations;
19-
consult the zlib manual at http://www.zlib.net/manual.html for authoritative
19+
consult the `zlib manual <https://www.zlib.net/manual.html>`_ for authoritative
2020
information.
2121

2222
For reading and writing ``.gz`` files see the :mod:`gzip` module.
@@ -340,6 +340,136 @@ Decompression objects support the following methods and attributes:
340340
objects.
341341

342342

343+
The following constants are available to configure compression and decompression
344+
behavior:
345+
346+
.. data:: DEFLATED
347+
348+
The deflate compression method.
349+
350+
351+
.. data:: MAX_WBITS
352+
353+
The maximum window size, expressed as a power of 2.
354+
For example, if :const:`!MAX_WBITS` is ``15`` it results in a window size
355+
of ``32 KiB``.
356+
357+
358+
.. data:: DEF_MEM_LEVEL
359+
360+
The default memory level for compression objects.
361+
362+
363+
.. data:: DEF_BUF_SIZE
364+
365+
The default buffer size for decompression operations.
366+
367+
368+
.. data:: Z_NO_COMPRESSION
369+
370+
Compression level ``0``.
371+
372+
.. versionadded:: 3.6
373+
374+
375+
.. data:: Z_BEST_SPEED
376+
377+
Compression level ``1``.
378+
379+
380+
.. data:: Z_BEST_COMPRESSION
381+
382+
Compression level ``9``.
383+
384+
385+
.. data:: Z_DEFAULT_COMPRESSION
386+
387+
Default compression level (``-1``).
388+
389+
390+
.. data:: Z_DEFAULT_STRATEGY
391+
392+
Default compression strategy, for normal data.
393+
394+
395+
.. data:: Z_FILTERED
396+
397+
Compression strategy for data produced by a filter (or predictor).
398+
399+
400+
.. data:: Z_HUFFMAN_ONLY
401+
402+
Compression strategy that forces Huffman coding only.
403+
404+
405+
.. data:: Z_RLE
406+
407+
Compression strategy that limits match distances to one (run-length encoding).
408+
409+
This constant is only available if Python was compiled with zlib
410+
1.2.0.1 or greater.
411+
412+
.. versionadded:: 3.6
413+
414+
415+
.. data:: Z_FIXED
416+
417+
Compression strategy that prevents the use of dynamic Huffman codes.
418+
419+
This constant is only available if Python was compiled with zlib
420+
1.2.2.2 or greater.
421+
422+
.. versionadded:: 3.6
423+
424+
425+
.. data:: Z_NO_FLUSH
426+
427+
Flush mode ``0``. No special flushing behavior.
428+
429+
.. versionadded:: 3.6
430+
431+
432+
.. data:: Z_PARTIAL_FLUSH
433+
434+
Flush mode ``1``. Flush as much output as possible.
435+
436+
437+
.. data:: Z_SYNC_FLUSH
438+
439+
Flush mode ``2``. All output is flushed and the output is aligned to a byte boundary.
440+
441+
442+
.. data:: Z_FULL_FLUSH
443+
444+
Flush mode ``3``. All output is flushed and the compression state is reset.
445+
446+
447+
.. data:: Z_FINISH
448+
449+
Flush mode ``4``. All pending input is processed, no more input is expected.
450+
451+
452+
.. data:: Z_BLOCK
453+
454+
Flush mode ``5``. A deflate block is completed and emitted.
455+
456+
This constant is only available if Python was compiled with zlib
457+
1.2.2.2 or greater.
458+
459+
.. versionadded:: 3.6
460+
461+
462+
.. data:: Z_TREES
463+
464+
Flush mode ``6``, for inflate operations. Instructs inflate to return when
465+
it gets to the next deflate block boundary.
466+
467+
This constant is only available if Python was compiled with zlib
468+
1.2.3.4 or greater.
469+
470+
.. versionadded:: 3.6
471+
472+
343473
Information about the version of the zlib library in use is available through
344474
the following constants:
345475

@@ -375,10 +505,10 @@ the following constants:
375505
Module :mod:`gzip`
376506
Reading and writing :program:`gzip`\ -format files.
377507

378-
http://www.zlib.net
508+
https://www.zlib.net
379509
The zlib library home page.
380510

381-
http://www.zlib.net/manual.html
511+
https://www.zlib.net/manual.html
382512
The zlib manual explains the semantics and usage of the library's many
383513
functions.
384514

Doc/tools/.nitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ Doc/library/xml.sax.reader.rst
5151
Doc/library/xml.sax.rst
5252
Doc/library/xmlrpc.client.rst
5353
Doc/library/xmlrpc.server.rst
54-
Doc/library/zlib.rst
5554
Doc/whatsnew/2.4.rst
5655
Doc/whatsnew/2.5.rst
5756
Doc/whatsnew/2.6.rst

Lib/pathlib/__init__.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -490,16 +490,19 @@ def relative_to(self, other, *, walk_up=False):
490490
"""
491491
if not hasattr(other, 'with_segments'):
492492
other = self.with_segments(other)
493-
for step, path in enumerate(chain([other], other.parents)):
493+
parts = []
494+
for path in chain([other], other.parents):
494495
if path == self or path in self.parents:
495496
break
496497
elif not walk_up:
497498
raise ValueError(f"{str(self)!r} is not in the subpath of {str(other)!r}")
498499
elif path.name == '..':
499500
raise ValueError(f"'..' segment in {str(other)!r} cannot be walked")
501+
else:
502+
parts.append('..')
500503
else:
501504
raise ValueError(f"{str(self)!r} and {str(other)!r} have different anchors")
502-
parts = ['..'] * step + self._tail[len(path._tail):]
505+
parts.extend(self._tail[len(path._tail):])
503506
return self._from_parsed_parts('', '', parts)
504507

505508
def is_relative_to(self, other):

Lib/pathlib/types.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,33 @@ def parents(self):
234234
parent = split(path)[0]
235235
return tuple(parents)
236236

237+
def relative_to(self, other, *, walk_up=False):
238+
"""Return the relative path to another path identified by the passed
239+
arguments. If the operation is not possible (because this is not
240+
related to the other path), raise ValueError.
241+
242+
The *walk_up* parameter controls whether `..` may be used to resolve
243+
the path.
244+
"""
245+
parts = []
246+
for path in (other,) + other.parents:
247+
if self.is_relative_to(path):
248+
break
249+
elif not walk_up:
250+
raise ValueError(f"{self!r} is not in the subpath of {other!r}")
251+
elif path.name == '..':
252+
raise ValueError(f"'..' segment in {other!r} cannot be walked")
253+
else:
254+
parts.append('..')
255+
else:
256+
raise ValueError(f"{self!r} and {other!r} have different anchors")
257+
return self.with_segments(*parts, *self.parts[len(path.parts):])
258+
259+
def is_relative_to(self, other):
260+
"""Return True if the path is relative to another path or False.
261+
"""
262+
return other == self or other in self.parents
263+
237264
def full_match(self, pattern):
238265
"""
239266
Return True if this path matches the given glob-style pattern. The

Lib/test/test_asyncio/test_unix_events.py

Lines changed: 61 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1180,32 +1180,68 @@ async def runner():
11801180

11811181

11821182
@support.requires_fork()
1183-
class TestFork(unittest.IsolatedAsyncioTestCase):
1183+
class TestFork(unittest.TestCase):
11841184

1185-
async def test_fork_not_share_event_loop(self):
1186-
with warnings_helper.ignore_fork_in_thread_deprecation_warnings():
1187-
# The forked process should not share the event loop with the parent
1188-
loop = asyncio.get_running_loop()
1189-
r, w = os.pipe()
1190-
self.addCleanup(os.close, r)
1191-
self.addCleanup(os.close, w)
1192-
pid = os.fork()
1193-
if pid == 0:
1194-
# child
1195-
try:
1196-
loop = asyncio.get_event_loop()
1197-
os.write(w, b'LOOP:' + str(id(loop)).encode())
1198-
except RuntimeError:
1199-
os.write(w, b'NO LOOP')
1200-
except BaseException as e:
1201-
os.write(w, b'ERROR:' + ascii(e).encode())
1202-
finally:
1203-
os._exit(0)
1204-
else:
1205-
# parent
1206-
result = os.read(r, 100)
1207-
self.assertEqual(result, b'NO LOOP')
1208-
wait_process(pid, exitcode=0)
1185+
@warnings_helper.ignore_fork_in_thread_deprecation_warnings()
1186+
def test_fork_not_share_current_task(self):
1187+
loop = object()
1188+
task = object()
1189+
asyncio._set_running_loop(loop)
1190+
self.addCleanup(asyncio._set_running_loop, None)
1191+
asyncio.tasks._enter_task(loop, task)
1192+
self.addCleanup(asyncio.tasks._leave_task, loop, task)
1193+
self.assertIs(asyncio.current_task(), task)
1194+
r, w = os.pipe()
1195+
self.addCleanup(os.close, r)
1196+
self.addCleanup(os.close, w)
1197+
pid = os.fork()
1198+
if pid == 0:
1199+
# child
1200+
try:
1201+
asyncio._set_running_loop(loop)
1202+
current_task = asyncio.current_task()
1203+
if current_task is None:
1204+
os.write(w, b'NO TASK')
1205+
else:
1206+
os.write(w, b'TASK:' + str(id(current_task)).encode())
1207+
except BaseException as e:
1208+
os.write(w, b'ERROR:' + ascii(e).encode())
1209+
finally:
1210+
asyncio._set_running_loop(None)
1211+
os._exit(0)
1212+
else:
1213+
# parent
1214+
result = os.read(r, 100)
1215+
self.assertEqual(result, b'NO TASK')
1216+
wait_process(pid, exitcode=0)
1217+
1218+
@warnings_helper.ignore_fork_in_thread_deprecation_warnings()
1219+
def test_fork_not_share_event_loop(self):
1220+
# The forked process should not share the event loop with the parent
1221+
loop = object()
1222+
asyncio._set_running_loop(loop)
1223+
self.assertIs(asyncio.get_running_loop(), loop)
1224+
self.addCleanup(asyncio._set_running_loop, None)
1225+
r, w = os.pipe()
1226+
self.addCleanup(os.close, r)
1227+
self.addCleanup(os.close, w)
1228+
pid = os.fork()
1229+
if pid == 0:
1230+
# child
1231+
try:
1232+
loop = asyncio.get_event_loop()
1233+
os.write(w, b'LOOP:' + str(id(loop)).encode())
1234+
except RuntimeError:
1235+
os.write(w, b'NO LOOP')
1236+
except BaseException as e:
1237+
os.write(w, b'ERROR:' + ascii(e).encode())
1238+
finally:
1239+
os._exit(0)
1240+
else:
1241+
# parent
1242+
result = os.read(r, 100)
1243+
self.assertEqual(result, b'NO LOOP')
1244+
wait_process(pid, exitcode=0)
12091245

12101246
@warnings_helper.ignore_fork_in_thread_deprecation_warnings()
12111247
@hashlib_helper.requires_hashdigest('md5')

Lib/test/test_exceptions.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,8 @@ def check(self, src, lineno, offset, end_lineno=None, end_offset=None, encoding=
224224
if not isinstance(src, str):
225225
src = src.decode(encoding, 'replace')
226226
line = src.split('\n')[lineno-1]
227+
if lineno == 1:
228+
line = line.removeprefix('\ufeff')
227229
self.assertIn(line, cm.exception.text)
228230

229231
def test_error_offset_continuation_characters(self):
@@ -239,7 +241,9 @@ def testSyntaxErrorOffset(self):
239241
check('Python = "\u1e54\xfd\u0163\u0125\xf2\xf1" +', 1, 20)
240242
check(b'# -*- coding: cp1251 -*-\nPython = "\xcf\xb3\xf2\xee\xed" +',
241243
2, 19, encoding='cp1251')
242-
check(b'Python = "\xcf\xb3\xf2\xee\xed" +', 1, 10)
244+
check(b'Python = "\xcf\xb3\xf2\xee\xed" +', 1, 12)
245+
check(b'\n\n\nPython = "\xcf\xb3\xf2\xee\xed" +', 4, 12)
246+
check(b'\xef\xbb\xbfPython = "\xcf\xb3\xf2\xee\xed" +', 1, 12)
243247
check('x = "a', 1, 5)
244248
check('lambda x: x = 2', 1, 1)
245249
check('f{a + b + c}', 1, 2)
@@ -287,7 +291,7 @@ def baz():
287291
check("pass\npass\npass\n(1+)\npass\npass\npass", 4, 4)
288292
check("(1+)", 1, 4)
289293
check("[interesting\nfoo()\n", 1, 1)
290-
check(b"\xef\xbb\xbf#coding: utf8\nprint('\xe6\x88\x91')\n", 0, -1)
294+
check(b"\xef\xbb\xbf#coding: utf8\nprint('\xe6\x88\x91')\n", 1, 0)
291295
check("""f'''
292296
{
293297
(123_a)

0 commit comments

Comments
 (0)