Skip to content

Commit e59cb27

Browse files
committed
1 parent df9f707 commit e59cb27

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

80 files changed

+587
-476
lines changed

PythonLib/full/argparse.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,9 @@ def _format_actions_usage(self, actions, groups):
392392
group_actions = set()
393393
inserts = {}
394394
for group in groups:
395+
if not group._group_actions:
396+
raise ValueError(f'empty group {group}')
397+
395398
try:
396399
start = actions.index(group._group_actions[0])
397400
except ValueError:
@@ -1669,7 +1672,8 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer):
16691672
"""Object for parsing command line strings into Python objects.
16701673
16711674
Keyword Arguments:
1672-
- prog -- The name of the program (default: sys.argv[0])
1675+
- prog -- The name of the program (default:
1676+
``os.path.basename(sys.argv[0])``)
16731677
- usage -- A usage message (default: auto-generated from arguments)
16741678
- description -- A description of what the program does
16751679
- epilog -- Text following the argument descriptions

PythonLib/full/asyncio/events.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -258,13 +258,13 @@ def _timer_handle_cancelled(self, handle):
258258
"""Notification that a TimerHandle has been cancelled."""
259259
raise NotImplementedError
260260

261-
def call_soon(self, callback, *args):
262-
return self.call_later(0, callback, *args)
261+
def call_soon(self, callback, *args, context=None):
262+
return self.call_later(0, callback, *args, context=context)
263263

264-
def call_later(self, delay, callback, *args):
264+
def call_later(self, delay, callback, *args, context=None):
265265
raise NotImplementedError
266266

267-
def call_at(self, when, callback, *args):
267+
def call_at(self, when, callback, *args, context=None):
268268
raise NotImplementedError
269269

270270
def time(self):
@@ -280,7 +280,7 @@ def create_task(self, coro, *, name=None):
280280

281281
# Methods for interacting with threads.
282282

283-
def call_soon_threadsafe(self, callback, *args):
283+
def call_soon_threadsafe(self, callback, *args, context=None):
284284
raise NotImplementedError
285285

286286
def run_in_executor(self, executor, func, *args):

PythonLib/full/asyncio/windows_events.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
"""Selector and proactor event loops for Windows."""
22

3+
import sys
4+
5+
if sys.platform != 'win32': # pragma: no cover
6+
raise ImportError('win32 only')
7+
38
import _overlapped
49
import _winapi
510
import errno

PythonLib/full/concurrent/futures/_base.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -284,13 +284,14 @@ def wait(fs, timeout=None, return_when=ALL_COMPLETED):
284284
A named 2-tuple of sets. The first set, named 'done', contains the
285285
futures that completed (is finished or cancelled) before the wait
286286
completed. The second set, named 'not_done', contains uncompleted
287-
futures.
287+
futures. Duplicate futures given to *fs* are removed and will be
288+
returned only once.
288289
"""
290+
fs = set(fs)
289291
with _AcquireFutures(fs):
290-
done = set(f for f in fs
291-
if f._state in [CANCELLED_AND_NOTIFIED, FINISHED])
292-
not_done = set(fs) - done
293-
292+
done = {f for f in fs
293+
if f._state in [CANCELLED_AND_NOTIFIED, FINISHED]}
294+
not_done = fs - done
294295
if (return_when == FIRST_COMPLETED) and done:
295296
return DoneAndNotDoneFutures(done, not_done)
296297
elif (return_when == FIRST_EXCEPTION) and done:
@@ -309,7 +310,7 @@ def wait(fs, timeout=None, return_when=ALL_COMPLETED):
309310
f._waiters.remove(waiter)
310311

311312
done.update(waiter.finished_futures)
312-
return DoneAndNotDoneFutures(done, set(fs) - done)
313+
return DoneAndNotDoneFutures(done, fs - done)
313314

314315
class Future(object):
315316
"""Represents the result of an asynchronous computation."""

PythonLib/full/ctypes/test/test_functions.py

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -35,34 +35,24 @@ def test_mro(self):
3535
# wasn't checked, and it even crashed Python.
3636
# Found by Greg Chapman.
3737

38-
try:
38+
with self.assertRaises(TypeError):
3939
class X(object, Array):
4040
_length_ = 5
4141
_type_ = "i"
42-
except TypeError:
43-
pass
44-
4542

4643
from _ctypes import _Pointer
47-
try:
44+
with self.assertRaises(TypeError):
4845
class X(object, _Pointer):
4946
pass
50-
except TypeError:
51-
pass
5247

5348
from _ctypes import _SimpleCData
54-
try:
49+
with self.assertRaises(TypeError):
5550
class X(object, _SimpleCData):
5651
_type_ = "i"
57-
except TypeError:
58-
pass
5952

60-
try:
53+
with self.assertRaises(TypeError):
6154
class X(object, Structure):
6255
_fields_ = []
63-
except TypeError:
64-
pass
65-
6656

6757
@need_symbol('c_wchar')
6858
def test_wchar_parm(self):

PythonLib/full/functools.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -740,6 +740,7 @@ def _compose_mro(cls, types):
740740
# Remove entries which are already present in the __mro__ or unrelated.
741741
def is_related(typ):
742742
return (typ not in bases and hasattr(typ, '__mro__')
743+
and not isinstance(typ, GenericAlias)
743744
and issubclass(cls, typ))
744745
types = [n for n in types if is_related(n)]
745746
# Remove entries which are strict bases of other entries (they will end up
@@ -837,16 +838,25 @@ def dispatch(cls):
837838
dispatch_cache[cls] = impl
838839
return impl
839840

841+
def _is_valid_dispatch_type(cls):
842+
return isinstance(cls, type) and not isinstance(cls, GenericAlias)
843+
840844
def register(cls, func=None):
841845
"""generic_func.register(cls, func) -> func
842846
843847
Registers a new implementation for the given *cls* on a *generic_func*.
844848
845849
"""
846850
nonlocal cache_token
847-
if func is None:
848-
if isinstance(cls, type):
851+
if _is_valid_dispatch_type(cls):
852+
if func is None:
849853
return lambda f: register(cls, f)
854+
else:
855+
if func is not None:
856+
raise TypeError(
857+
f"Invalid first argument to `register()`. "
858+
f"{cls!r} is not a class."
859+
)
850860
ann = getattr(cls, '__annotations__', {})
851861
if not ann:
852862
raise TypeError(
@@ -859,11 +869,12 @@ def register(cls, func=None):
859869
# only import typing if annotation parsing is necessary
860870
from typing import get_type_hints
861871
argname, cls = next(iter(get_type_hints(func).items()))
862-
if not isinstance(cls, type):
872+
if not _is_valid_dispatch_type(cls):
863873
raise TypeError(
864874
f"Invalid annotation for {argname!r}. "
865875
f"{cls!r} is not a class."
866876
)
877+
867878
registry[cls] = func
868879
if cache_token is None and hasattr(cls, '__abstractmethods__'):
869880
cache_token = get_cache_token()

PythonLib/full/importlib/metadata/__init__.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -669,16 +669,25 @@ def _convert_egg_info_reqs_to_simple_reqs(sections):
669669
def make_condition(name):
670670
return name and f'extra == "{name}"'
671671

672-
def parse_condition(section):
672+
def quoted_marker(section):
673673
section = section or ''
674674
extra, sep, markers = section.partition(':')
675675
if extra and markers:
676676
markers = f'({markers})'
677677
conditions = list(filter(None, [markers, make_condition(extra)]))
678678
return '; ' + ' and '.join(conditions) if conditions else ''
679679

680+
def url_req_space(req):
681+
"""
682+
PEP 508 requires a space between the url_spec and the quoted_marker.
683+
Ref python/importlib_metadata#357.
684+
"""
685+
# '@' is uniquely indicative of a url_req.
686+
return ' ' * ('@' in req)
687+
680688
for section in sections:
681-
yield section.value + parse_condition(section.name)
689+
space = url_req_space(section.value)
690+
yield section.value + space + quoted_marker(section.name)
682691

683692

684693
class DistributionFinder(MetaPathFinder):

PythonLib/full/json/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ def dump(obj, fp, *, skipkeys=False, ensure_ascii=True, check_circular=True,
133133
134134
If ``check_circular`` is false, then the circular reference check
135135
for container types will be skipped and a circular reference will
136-
result in an ``OverflowError`` (or worse).
136+
result in an ``RecursionError`` (or worse).
137137
138138
If ``allow_nan`` is false, then it will be a ``ValueError`` to
139139
serialize out of range ``float`` values (``nan``, ``inf``, ``-inf``)
@@ -195,7 +195,7 @@ def dumps(obj, *, skipkeys=False, ensure_ascii=True, check_circular=True,
195195
196196
If ``check_circular`` is false, then the circular reference check
197197
for container types will be skipped and a circular reference will
198-
result in an ``OverflowError`` (or worse).
198+
result in an ``RecursionError`` (or worse).
199199
200200
If ``allow_nan`` is false, then it will be a ``ValueError`` to
201201
serialize out of range ``float`` values (``nan``, ``inf``, ``-inf``) in

PythonLib/full/json/encoder.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ def __init__(self, *, skipkeys=False, ensure_ascii=True,
116116
117117
If check_circular is true, then lists, dicts, and custom encoded
118118
objects will be checked for circular references during encoding to
119-
prevent an infinite recursion (which would cause an OverflowError).
119+
prevent an infinite recursion (which would cause an RecursionError).
120120
Otherwise, no such check takes place.
121121
122122
If allow_nan is true, then NaN, Infinity, and -Infinity will be

PythonLib/full/logging/__init__.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -878,6 +878,7 @@ def __init__(self, level=NOTSET):
878878
self._name = None
879879
self.level = _checkLevel(level)
880880
self.formatter = None
881+
self._closed = False
881882
# Add the handler to the global _handlerList (for cleanup on shutdown)
882883
_addHandlerRef(self)
883884
self.createLock()
@@ -996,6 +997,7 @@ def close(self):
996997
#get the module data lock, as we're updating a shared structure.
997998
_acquireLock()
998999
try: #unlikely to raise an exception, but you never know...
1000+
self._closed = True
9991001
if self._name and self._name in _handlers:
10001002
del _handlers[self._name]
10011003
finally:
@@ -1184,6 +1186,8 @@ def close(self):
11841186
finally:
11851187
# Issue #19523: call unconditionally to
11861188
# prevent a handler leak when delay is set
1189+
# Also see Issue #42378: we also rely on
1190+
# self._closed being set to True there
11871191
StreamHandler.close(self)
11881192
finally:
11891193
self.release()
@@ -1203,10 +1207,15 @@ def emit(self, record):
12031207
12041208
If the stream was not opened because 'delay' was specified in the
12051209
constructor, open it before calling the superclass's emit.
1210+
1211+
If stream is not open, current mode is 'w' and `_closed=True`, record
1212+
will not be emitted (see Issue #42378).
12061213
"""
12071214
if self.stream is None:
1208-
self.stream = self._open()
1209-
StreamHandler.emit(self, record)
1215+
if self.mode != 'w' or not self._closed:
1216+
self.stream = self._open()
1217+
if self.stream:
1218+
StreamHandler.emit(self, record)
12101219

12111220
def __repr__(self):
12121221
level = getLevelName(self.level)

0 commit comments

Comments
 (0)