Skip to content

Commit f29ca0b

Browse files
authored
Merge branch 'main' into fetch-restore
2 parents df86e20 + d71edbd commit f29ca0b

15 files changed

+109
-56
lines changed

Doc/library/asyncio-eventloop.rst

+2-2
Original file line numberDiff line numberDiff line change
@@ -524,8 +524,8 @@ Opening network connections
524524
When a server's IPv4 path and protocol are working, but the server's
525525
IPv6 path and protocol are not working, a dual-stack client
526526
application experiences significant connection delay compared to an
527-
IPv4-only client. This is undesirable because it causes the dual-
528-
stack client to have a worse user experience. This document
527+
IPv4-only client. This is undesirable because it causes the
528+
dual-stack client to have a worse user experience. This document
529529
specifies requirements for algorithms that reduce this user-visible
530530
delay and provides an algorithm.
531531

Doc/library/typing.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -1588,7 +1588,7 @@ These are not used in annotations. They are building blocks for creating generic
15881588
methods, not their type signatures. For example, :class:`ssl.SSLObject`
15891589
is a class, therefore it passes an :func:`issubclass`
15901590
check against :data:`Callable`. However, the
1591-
:meth:`ssl.SSLObject.__init__` method exists only to raise a
1591+
``ssl.SSLObject.__init__`` method exists only to raise a
15921592
:exc:`TypeError` with a more informative message, therefore making
15931593
it impossible to call (instantiate) :class:`ssl.SSLObject`.
15941594

Lib/ensurepip/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
__all__ = ["version", "bootstrap"]
1212
_PACKAGE_NAMES = ('setuptools', 'pip')
1313
_SETUPTOOLS_VERSION = "65.5.0"
14-
_PIP_VERSION = "23.0"
14+
_PIP_VERSION = "23.0.1"
1515
_PROJECTS = [
1616
("setuptools", _SETUPTOOLS_VERSION, "py3"),
1717
("pip", _PIP_VERSION, "py3"),

Lib/test/test_bool.py

+6
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,12 @@ def test_float(self):
4040
self.assertEqual(float(True), 1.0)
4141
self.assertIsNot(float(True), True)
4242

43+
def test_complex(self):
44+
self.assertEqual(complex(False), 0j)
45+
self.assertEqual(complex(False), False)
46+
self.assertEqual(complex(True), 1+0j)
47+
self.assertEqual(complex(True), True)
48+
4349
def test_math(self):
4450
self.assertEqual(+False, 0)
4551
self.assertIsNot(+False, False)

Lib/test/test_zipfile/_context.py

-30
This file was deleted.

Lib/test/test_zipfile/_func_timeout_compat.py

-8
This file was deleted.

Lib/test/test_zipfile/_itertools.py

+38
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import itertools
2+
from collections import deque
3+
from itertools import islice
24

35

46
# from jaraco.itertools 6.3.0
@@ -39,3 +41,39 @@ def always_iterable(obj, base_type=(str, bytes)):
3941
return iter(obj)
4042
except TypeError:
4143
return iter((obj,))
44+
45+
46+
# from more_itertools v9.0.0
47+
def consume(iterator, n=None):
48+
"""Advance *iterable* by *n* steps. If *n* is ``None``, consume it
49+
entirely.
50+
Efficiently exhausts an iterator without returning values. Defaults to
51+
consuming the whole iterator, but an optional second argument may be
52+
provided to limit consumption.
53+
>>> i = (x for x in range(10))
54+
>>> next(i)
55+
0
56+
>>> consume(i, 3)
57+
>>> next(i)
58+
4
59+
>>> consume(i)
60+
>>> next(i)
61+
Traceback (most recent call last):
62+
File "<stdin>", line 1, in <module>
63+
StopIteration
64+
If the iterator has fewer items remaining than the provided limit, the
65+
whole iterator will be consumed.
66+
>>> i = (x for x in range(3))
67+
>>> consume(i, 5)
68+
>>> next(i)
69+
Traceback (most recent call last):
70+
File "<stdin>", line 1, in <module>
71+
StopIteration
72+
"""
73+
# Use functions that consume iterators at C speed.
74+
if n is None:
75+
# feed the entire iterator into a zero-length deque
76+
deque(iterator, maxlen=0)
77+
else:
78+
# advance to the empty slice starting at position n
79+
next(islice(iterator, n, n), None)

Lib/test/test_zipfile/_support.py

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import importlib
2+
import unittest
3+
4+
5+
def import_or_skip(name):
6+
try:
7+
return importlib.import_module(name)
8+
except ImportError: # pragma: no cover
9+
raise unittest.SkipTest(f'Unable to import {name}')
+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import unittest
2+
import string
3+
import zipfile
4+
5+
from ._functools import compose
6+
from ._itertools import consume
7+
8+
from ._support import import_or_skip
9+
10+
11+
big_o = import_or_skip('big_o')
12+
13+
14+
class TestComplexity(unittest.TestCase):
15+
def test_implied_dirs_performance(self):
16+
best, others = big_o.big_o(
17+
compose(consume, zipfile.CompleteDirs._implied_dirs),
18+
lambda size: [
19+
'/'.join(string.ascii_lowercase + str(n)) for n in range(size)
20+
],
21+
max_n=1000,
22+
min_n=1,
23+
)
24+
assert best <= big_o.complexities.Linear

Lib/test/test_zipfile/test_path.py

+10-12
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import contextlib
44
import pathlib
55
import pickle
6-
import string
76
import sys
87
import unittest
98
import zipfile
@@ -12,7 +11,6 @@
1211
from ._itertools import Counter
1312

1413
from ._test_params import parameterize, Invoked
15-
from ._func_timeout_compat import set_timeout
1614

1715
from test.support.os_helper import temp_dir
1816

@@ -22,9 +20,6 @@ class itertools:
2220
Counter = Counter
2321

2422

25-
consume = tuple
26-
27-
2823
def add_dirs(zf):
2924
"""
3025
Given a writable zip file zf, inject directory entries for
@@ -330,12 +325,6 @@ def test_joinpath_constant_time(self):
330325
# Check the file iterated all items
331326
assert entries.count == self.HUGE_ZIPFILE_NUM_ENTRIES
332327

333-
# timeout disabled due to #102209
334-
# @set_timeout(3)
335-
def test_implied_dirs_performance(self):
336-
data = ['/'.join(string.ascii_lowercase + str(n)) for n in range(10000)]
337-
zipfile.CompleteDirs._implied_dirs(data)
338-
339328
@pass_alpharep
340329
def test_read_does_not_close(self, alpharep):
341330
alpharep = self.zipfile_ondisk(alpharep)
@@ -513,7 +502,7 @@ def test_pickle(self, alpharep, path_type, subpath):
513502
saved_1 = pickle.dumps(zipfile.Path(zipfile_ondisk, at=subpath))
514503
restored_1 = pickle.loads(saved_1)
515504
first, *rest = restored_1.iterdir()
516-
assert first.read_text().startswith('content of ')
505+
assert first.read_text(encoding='utf-8').startswith('content of ')
517506

518507
@pass_alpharep
519508
def test_extract_orig_with_implied_dirs(self, alpharep):
@@ -525,3 +514,12 @@ def test_extract_orig_with_implied_dirs(self, alpharep):
525514
# wrap the zipfile for its side effect
526515
zipfile.Path(zf)
527516
zf.extractall(source_path.parent)
517+
518+
@pass_alpharep
519+
def test_getinfo_missing(self, alpharep):
520+
"""
521+
Validate behavior of getinfo on original zipfile after wrapping.
522+
"""
523+
zipfile.Path(alpharep)
524+
with self.assertRaises(KeyError):
525+
alpharep.getinfo('does-not-exist')

Lib/zipfile/_path.py

+6-1
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,11 @@ class CompleteDirs(InitializedState, zipfile.ZipFile):
8686
"""
8787
A ZipFile subclass that ensures that implied directories
8888
are always included in the namelist.
89+
90+
>>> list(CompleteDirs._implied_dirs(['foo/bar.txt', 'foo/bar/baz.txt']))
91+
['foo/', 'foo/bar/']
92+
>>> list(CompleteDirs._implied_dirs(['foo/bar.txt', 'foo/bar/baz.txt', 'foo/bar/']))
93+
['foo/']
8994
"""
9095

9196
@staticmethod
@@ -215,7 +220,7 @@ class Path:
215220
216221
Read text:
217222
218-
>>> c.read_text()
223+
>>> c.read_text(encoding='utf-8')
219224
'content of c'
220225
221226
existence:
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Upgrade pip wheel bundled with ensurepip (pip 23.0.1)

Objects/listobject.c

+8
Original file line numberDiff line numberDiff line change
@@ -3451,16 +3451,24 @@ listiter_reduce_general(void *_it, int forward)
34513451
/* the objects are not the same, index is of different types! */
34523452
if (forward) {
34533453
PyObject *iter = _PyEval_GetBuiltin(&_Py_ID(iter));
3454+
if (!iter) {
3455+
return NULL;
3456+
}
34543457
_PyListIterObject *it = (_PyListIterObject *)_it;
34553458
if (it->it_seq) {
34563459
return Py_BuildValue("N(O)n", iter, it->it_seq, it->it_index);
34573460
}
3461+
Py_DECREF(iter);
34583462
} else {
34593463
PyObject *reversed = _PyEval_GetBuiltin(&_Py_ID(reversed));
3464+
if (!reversed) {
3465+
return NULL;
3466+
}
34603467
listreviterobject *it = (listreviterobject *)_it;
34613468
if (it->it_seq) {
34623469
return Py_BuildValue("N(O)n", reversed, it->it_seq, it->it_index);
34633470
}
3471+
Py_DECREF(reversed);
34643472
}
34653473
/* empty iterator, create an empty list */
34663474
list = PyList_New(0);

Objects/unicodeobject.c

+3-1
Original file line numberDiff line numberDiff line change
@@ -14794,8 +14794,10 @@ unicodeiter_reduce(unicodeiterobject *it, PyObject *Py_UNUSED(ignored))
1479414794
return Py_BuildValue("N(O)n", iter, it->it_seq, it->it_index);
1479514795
} else {
1479614796
PyObject *u = unicode_new_empty();
14797-
if (u == NULL)
14797+
if (u == NULL) {
14798+
Py_DECREF(iter);
1479814799
return NULL;
14800+
}
1479914801
return Py_BuildValue("N(N)", iter, u);
1480014802
}
1480114803
}

0 commit comments

Comments
 (0)