Skip to content

Commit a5068fa

Browse files
committed
update to python 3.10.5
1 parent 3d2152f commit a5068fa

File tree

103 files changed

+602
-305
lines changed

Some content is hidden

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

103 files changed

+602
-305
lines changed

PythonLib/full/argparse.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -848,6 +848,7 @@ def _get_kwargs(self):
848848
'default',
849849
'type',
850850
'choices',
851+
'required',
851852
'help',
852853
'metavar',
853854
]

PythonLib/full/asyncio/base_events.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -884,7 +884,7 @@ async def _sock_sendfile_native(self, sock, file, offset, count):
884884
# non-mmap files even if sendfile is supported by OS
885885
raise exceptions.SendfileNotAvailableError(
886886
f"syscall sendfile is not available for socket {sock!r} "
887-
"and file {file!r} combination")
887+
f"and file {file!r} combination")
888888

889889
async def _sock_sendfile_fallback(self, sock, file, offset, count):
890890
if offset:

PythonLib/full/asyncio/selector_events.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -487,7 +487,8 @@ async def sock_connect(self, sock, address):
487487
if self._debug and sock.gettimeout() != 0:
488488
raise ValueError("the socket must be non-blocking")
489489

490-
if not hasattr(socket, 'AF_UNIX') or sock.family != socket.AF_UNIX:
490+
if sock.family == socket.AF_INET or (
491+
base_events._HAS_IPv6 and sock.family == socket.AF_INET6):
491492
resolved = await self._ensure_resolved(
492493
address, family=sock.family, type=sock.type, proto=sock.proto,
493494
loop=self,

PythonLib/full/concurrent/futures/_base.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -381,7 +381,7 @@ def running(self):
381381
return self._state == RUNNING
382382

383383
def done(self):
384-
"""Return True of the future was cancelled or finished executing."""
384+
"""Return True if the future was cancelled or finished executing."""
385385
with self._condition:
386386
return self._state in [CANCELLED, CANCELLED_AND_NOTIFIED, FINISHED]
387387

PythonLib/full/concurrent/futures/process.py

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,9 @@ def __init__(self, exc, tb):
126126
tb = traceback.format_exception(type(exc), exc, tb)
127127
tb = ''.join(tb)
128128
self.exc = exc
129+
# Traceback object needs to be garbage-collected as its frames
130+
# contain references to all the objects in the exception scope
131+
self.exc.__traceback__ = None
129132
self.tb = '\n"""\n%s"""' % tb
130133
def __reduce__(self):
131134
return _rebuild_exc, (self.exc, self.tb)
@@ -612,6 +615,10 @@ def __init__(self, max_workers=None, mp_context=None,
612615
mp_context = mp.get_context()
613616
self._mp_context = mp_context
614617

618+
# https://github.com/python/cpython/issues/90622
619+
self._safe_to_dynamically_spawn_children = (
620+
self._mp_context.get_start_method(allow_none=False) != "fork")
621+
615622
if initializer is not None and not callable(initializer):
616623
raise TypeError("initializer must be a callable")
617624
self._initializer = initializer
@@ -662,6 +669,8 @@ def __init__(self, max_workers=None, mp_context=None,
662669
def _start_executor_manager_thread(self):
663670
if self._executor_manager_thread is None:
664671
# Start the processes so that their sentinels are known.
672+
if not self._safe_to_dynamically_spawn_children: # ie, using fork.
673+
self._launch_processes()
665674
self._executor_manager_thread = _ExecutorManagerThread(self)
666675
self._executor_manager_thread.start()
667676
_threads_wakeups[self._executor_manager_thread] = \
@@ -674,14 +683,31 @@ def _adjust_process_count(self):
674683

675684
process_count = len(self._processes)
676685
if process_count < self._max_workers:
677-
p = self._mp_context.Process(
678-
target=_process_worker,
679-
args=(self._call_queue,
680-
self._result_queue,
681-
self._initializer,
682-
self._initargs))
683-
p.start()
684-
self._processes[p.pid] = p
686+
# Assertion disabled as this codepath is also used to replace a
687+
# worker that unexpectedly dies, even when using the 'fork' start
688+
# method. That means there is still a potential deadlock bug. If a
689+
# 'fork' mp_context worker dies, we'll be forking a new one when
690+
# we know a thread is running (self._executor_manager_thread).
691+
#assert self._safe_to_dynamically_spawn_children or not self._executor_manager_thread, 'https://github.com/python/cpython/issues/90622'
692+
self._spawn_process()
693+
694+
def _launch_processes(self):
695+
# https://github.com/python/cpython/issues/90622
696+
assert not self._executor_manager_thread, (
697+
'Processes cannot be fork()ed after the thread has started, '
698+
'deadlock in the child processes could result.')
699+
for _ in range(len(self._processes), self._max_workers):
700+
self._spawn_process()
701+
702+
def _spawn_process(self):
703+
p = self._mp_context.Process(
704+
target=_process_worker,
705+
args=(self._call_queue,
706+
self._result_queue,
707+
self._initializer,
708+
self._initargs))
709+
p.start()
710+
self._processes[p.pid] = p
685711

686712
def submit(self, fn, /, *args, **kwargs):
687713
with self._shutdown_lock:
@@ -702,7 +728,8 @@ def submit(self, fn, /, *args, **kwargs):
702728
# Wake up queue management thread
703729
self._executor_manager_thread_wakeup.wakeup()
704730

705-
self._adjust_process_count()
731+
if self._safe_to_dynamically_spawn_children:
732+
self._adjust_process_count()
706733
self._start_executor_manager_thread()
707734
return f
708735
submit.__doc__ = _base.Executor.submit.__doc__

PythonLib/full/datetime.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1652,7 +1652,7 @@ def _fromtimestamp(cls, t, utc, tz):
16521652
y, m, d, hh, mm, ss, weekday, jday, dst = converter(t)
16531653
ss = min(ss, 59) # clamp out leap seconds if the platform has them
16541654
result = cls(y, m, d, hh, mm, ss, us, tz)
1655-
if tz is None:
1655+
if tz is None and not utc:
16561656
# As of version 2015f max fold in IANA database is
16571657
# 23 hours at 1969-09-30 13:00:00 in Kwajalein.
16581658
# Let's probe 24 hours in the past to detect a transition:
@@ -1673,7 +1673,7 @@ def _fromtimestamp(cls, t, utc, tz):
16731673
probe2 = cls(y, m, d, hh, mm, ss, us, tz)
16741674
if probe2 == result:
16751675
result._fold = 1
1676-
else:
1676+
elif tz is not None:
16771677
result = tz.fromutc(result)
16781678
return result
16791679

PythonLib/full/difflib.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -837,7 +837,7 @@ def compare(self, a, b):
837837
Each sequence must contain individual single-line strings ending with
838838
newlines. Such sequences can be obtained from the `readlines()` method
839839
of file-like objects. The delta generated also consists of newline-
840-
terminated strings, ready to be printed as-is via the writeline()
840+
terminated strings, ready to be printed as-is via the writelines()
841841
method of a file-like object.
842842
843843
Example:

PythonLib/full/doctest.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1085,19 +1085,21 @@ def _get_test(self, obj, name, module, globs, source_lines):
10851085

10861086
def _find_lineno(self, obj, source_lines):
10871087
"""
1088-
Return a line number of the given object's docstring. Note:
1089-
this method assumes that the object has a docstring.
1088+
Return a line number of the given object's docstring.
1089+
1090+
Returns `None` if the given object does not have a docstring.
10901091
"""
10911092
lineno = None
1093+
docstring = getattr(obj, '__doc__', None)
10921094

10931095
# Find the line number for modules.
1094-
if inspect.ismodule(obj):
1096+
if inspect.ismodule(obj) and docstring is not None:
10951097
lineno = 0
10961098

10971099
# Find the line number for classes.
10981100
# Note: this could be fooled if a class is defined multiple
10991101
# times in a single file.
1100-
if inspect.isclass(obj):
1102+
if inspect.isclass(obj) and docstring is not None:
11011103
if source_lines is None:
11021104
return None
11031105
pat = re.compile(r'^\s*class\s*%s\b' %
@@ -1109,7 +1111,9 @@ def _find_lineno(self, obj, source_lines):
11091111

11101112
# Find the line number for functions & methods.
11111113
if inspect.ismethod(obj): obj = obj.__func__
1112-
if inspect.isfunction(obj): obj = obj.__code__
1114+
if inspect.isfunction(obj) and getattr(obj, '__doc__', None):
1115+
# We don't use `docstring` var here, because `obj` can be changed.
1116+
obj = obj.__code__
11131117
if inspect.istraceback(obj): obj = obj.tb_frame
11141118
if inspect.isframe(obj): obj = obj.f_code
11151119
if inspect.iscode(obj):

PythonLib/full/email/_encoded_words.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -179,15 +179,15 @@ def decode(ew):
179179
# Turn the CTE decoded bytes into unicode.
180180
try:
181181
string = bstring.decode(charset)
182-
except UnicodeError:
182+
except UnicodeDecodeError:
183183
defects.append(errors.UndecodableBytesDefect("Encoded word "
184-
"contains bytes not decodable using {} charset".format(charset)))
184+
f"contains bytes not decodable using {charset!r} charset"))
185185
string = bstring.decode(charset, 'surrogateescape')
186-
except LookupError:
186+
except (LookupError, UnicodeEncodeError):
187187
string = bstring.decode('ascii', 'surrogateescape')
188188
if charset.lower() != 'unknown-8bit':
189-
defects.append(errors.CharsetError("Unknown charset {} "
190-
"in encoded word; decoded as unknown bytes".format(charset)))
189+
defects.append(errors.CharsetError(f"Unknown charset {charset!r} "
190+
f"in encoded word; decoded as unknown bytes"))
191191
return string, charset, lang, defects
192192

193193

PythonLib/full/email/_header_value_parser.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -781,7 +781,7 @@ def params(self):
781781
else:
782782
try:
783783
value = value.decode(charset, 'surrogateescape')
784-
except LookupError:
784+
except (LookupError, UnicodeEncodeError):
785785
# XXX: there should really be a custom defect for
786786
# unknown character set to make it easy to find,
787787
# because otherwise unknown charset is a silent
@@ -2379,7 +2379,7 @@ def get_section(value):
23792379
digits += value[0]
23802380
value = value[1:]
23812381
if digits[0] == '0' and digits != '0':
2382-
section.defects.append(errors.InvalidHeaderError(
2382+
section.defects.append(errors.InvalidHeaderDefect(
23832383
"section number has an invalid leading 0"))
23842384
section.number = int(digits)
23852385
section.append(ValueTerminal(digits, 'digits'))

0 commit comments

Comments
 (0)