Skip to content

Commit 2d5e130

Browse files
committed
update python to 3.10.8
1 parent c4248ff commit 2d5e130

Some content is hidden

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

96 files changed

+628
-372
lines changed

PythonLib/full/ast.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,12 @@ def parse(source, filename='<unknown>', mode='exec', *,
5353

5454
def literal_eval(node_or_string):
5555
"""
56-
Safely evaluate an expression node or a string containing a Python
56+
Evaluate an expression node or a string containing only a Python
5757
expression. The string or node provided may only consist of the following
5858
Python literal structures: strings, bytes, numbers, tuples, lists, dicts,
5959
sets, booleans, and None.
60+
61+
Caution: A complex expression can overflow the C stack and cause a crash.
6062
"""
6163
if isinstance(node_or_string, str):
6264
node_or_string = parse(node_or_string.lstrip(" \t"), mode='eval')
@@ -849,7 +851,7 @@ def visit_Import(self, node):
849851

850852
def visit_ImportFrom(self, node):
851853
self.fill("from ")
852-
self.write("." * node.level)
854+
self.write("." * (node.level or 0))
853855
if node.module:
854856
self.write(node.module)
855857
self.write(" import ")

PythonLib/full/asyncio/base_events.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -573,9 +573,11 @@ async def shutdown_default_executor(self):
573573
def _do_shutdown(self, future):
574574
try:
575575
self._default_executor.shutdown(wait=True)
576-
self.call_soon_threadsafe(future.set_result, None)
576+
if not self.is_closed():
577+
self.call_soon_threadsafe(future.set_result, None)
577578
except Exception as ex:
578-
self.call_soon_threadsafe(future.set_exception, ex)
579+
if not self.is_closed():
580+
self.call_soon_threadsafe(future.set_exception, ex)
579581

580582
def _check_running(self):
581583
if self.is_running():
@@ -589,12 +591,13 @@ def run_forever(self):
589591
self._check_closed()
590592
self._check_running()
591593
self._set_coroutine_origin_tracking(self._debug)
592-
self._thread_id = threading.get_ident()
593594

594595
old_agen_hooks = sys.get_asyncgen_hooks()
595-
sys.set_asyncgen_hooks(firstiter=self._asyncgen_firstiter_hook,
596-
finalizer=self._asyncgen_finalizer_hook)
597596
try:
597+
self._thread_id = threading.get_ident()
598+
sys.set_asyncgen_hooks(firstiter=self._asyncgen_firstiter_hook,
599+
finalizer=self._asyncgen_finalizer_hook)
600+
598601
events._set_running_loop(self)
599602
while True:
600603
self._run_once()

PythonLib/full/asyncio/futures.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -396,6 +396,8 @@ def _call_set_state(source):
396396
if dest_loop is None or dest_loop is source_loop:
397397
_set_state(destination, source)
398398
else:
399+
if dest_loop.is_closed():
400+
return
399401
dest_loop.call_soon_threadsafe(_set_state, destination, source)
400402

401403
destination.add_done_callback(_call_check_cancel)

PythonLib/full/asyncio/locks.py

Lines changed: 38 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -349,9 +349,8 @@ def __init__(self, value=1, *, loop=mixins._marker):
349349
super().__init__(loop=loop)
350350
if value < 0:
351351
raise ValueError("Semaphore initial value must be >= 0")
352+
self._waiters = None
352353
self._value = value
353-
self._waiters = collections.deque()
354-
self._wakeup_scheduled = False
355354

356355
def __repr__(self):
357356
res = super().__repr__()
@@ -360,17 +359,10 @@ def __repr__(self):
360359
extra = f'{extra}, waiters:{len(self._waiters)}'
361360
return f'<{res[1:-1]} [{extra}]>'
362361

363-
def _wake_up_next(self):
364-
while self._waiters:
365-
waiter = self._waiters.popleft()
366-
if not waiter.done():
367-
waiter.set_result(None)
368-
self._wakeup_scheduled = True
369-
return
370-
371362
def locked(self):
372-
"""Returns True if semaphore can not be acquired immediately."""
373-
return self._value == 0
363+
"""Returns True if semaphore cannot be acquired immediately."""
364+
return self._value == 0 or (
365+
any(not w.cancelled() for w in (self._waiters or ())))
374366

375367
async def acquire(self):
376368
"""Acquire a semaphore.
@@ -381,29 +373,53 @@ async def acquire(self):
381373
called release() to make it larger than 0, and then return
382374
True.
383375
"""
384-
# _wakeup_scheduled is set if *another* task is scheduled to wakeup
385-
# but its acquire() is not resumed yet
386-
while self._wakeup_scheduled or self._value <= 0:
387-
fut = self._get_loop().create_future()
388-
self._waiters.append(fut)
376+
if not self.locked():
377+
self._value -= 1
378+
return True
379+
380+
if self._waiters is None:
381+
self._waiters = collections.deque()
382+
fut = self._get_loop().create_future()
383+
self._waiters.append(fut)
384+
385+
# Finally block should be called before the CancelledError
386+
# handling as we don't want CancelledError to call
387+
# _wake_up_first() and attempt to wake up itself.
388+
try:
389389
try:
390390
await fut
391-
# reset _wakeup_scheduled *after* waiting for a future
392-
self._wakeup_scheduled = False
393-
except exceptions.CancelledError:
391+
finally:
392+
self._waiters.remove(fut)
393+
except exceptions.CancelledError:
394+
if not fut.cancelled():
395+
self._value += 1
394396
self._wake_up_next()
395-
raise
396-
self._value -= 1
397+
raise
398+
399+
if self._value > 0:
400+
self._wake_up_next()
397401
return True
398402

399403
def release(self):
400404
"""Release a semaphore, incrementing the internal counter by one.
405+
401406
When it was zero on entry and another coroutine is waiting for it to
402407
become larger than zero again, wake up that coroutine.
403408
"""
404409
self._value += 1
405410
self._wake_up_next()
406411

412+
def _wake_up_next(self):
413+
"""Wake up the first waiter that isn't done."""
414+
if not self._waiters:
415+
return
416+
417+
for fut in self._waiters:
418+
if not fut.done():
419+
self._value -= 1
420+
fut.set_result(True)
421+
return
422+
407423

408424
class BoundedSemaphore(Semaphore):
409425
"""A bounded semaphore implementation.

PythonLib/full/asyncio/streams.py

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
'StreamReader', 'StreamWriter', 'StreamReaderProtocol',
33
'open_connection', 'start_server')
44

5+
import collections
56
import socket
67
import sys
78
import warnings
@@ -129,7 +130,7 @@ def __init__(self, loop=None):
129130
else:
130131
self._loop = loop
131132
self._paused = False
132-
self._drain_waiter = None
133+
self._drain_waiters = collections.deque()
133134
self._connection_lost = False
134135

135136
def pause_writing(self):
@@ -144,38 +145,34 @@ def resume_writing(self):
144145
if self._loop.get_debug():
145146
logger.debug("%r resumes writing", self)
146147

147-
waiter = self._drain_waiter
148-
if waiter is not None:
149-
self._drain_waiter = None
148+
for waiter in self._drain_waiters:
150149
if not waiter.done():
151150
waiter.set_result(None)
152151

153152
def connection_lost(self, exc):
154153
self._connection_lost = True
155-
# Wake up the writer if currently paused.
154+
# Wake up the writer(s) if currently paused.
156155
if not self._paused:
157156
return
158-
waiter = self._drain_waiter
159-
if waiter is None:
160-
return
161-
self._drain_waiter = None
162-
if waiter.done():
163-
return
164-
if exc is None:
165-
waiter.set_result(None)
166-
else:
167-
waiter.set_exception(exc)
157+
158+
for waiter in self._drain_waiters:
159+
if not waiter.done():
160+
if exc is None:
161+
waiter.set_result(None)
162+
else:
163+
waiter.set_exception(exc)
168164

169165
async def _drain_helper(self):
170166
if self._connection_lost:
171167
raise ConnectionResetError('Connection lost')
172168
if not self._paused:
173169
return
174-
waiter = self._drain_waiter
175-
assert waiter is None or waiter.cancelled()
176170
waiter = self._loop.create_future()
177-
self._drain_waiter = waiter
178-
await waiter
171+
self._drain_waiters.append(waiter)
172+
try:
173+
await waiter
174+
finally:
175+
self._drain_waiters.remove(waiter)
179176

180177
def _get_close_waiter(self, stream):
181178
raise NotImplementedError
@@ -206,6 +203,7 @@ def __init__(self, stream_reader, client_connected_cb=None, loop=None):
206203
self._strong_reader = stream_reader
207204
self._reject_connection = False
208205
self._stream_writer = None
206+
self._task = None
209207
self._transport = None
210208
self._client_connected_cb = client_connected_cb
211209
self._over_ssl = False
@@ -241,7 +239,7 @@ def connection_made(self, transport):
241239
res = self._client_connected_cb(reader,
242240
self._stream_writer)
243241
if coroutines.iscoroutine(res):
244-
self._loop.create_task(res)
242+
self._task = self._loop.create_task(res)
245243
self._strong_reader = None
246244

247245
def connection_lost(self, exc):
@@ -259,6 +257,7 @@ def connection_lost(self, exc):
259257
super().connection_lost(exc)
260258
self._stream_reader_wr = None
261259
self._stream_writer = None
260+
self._task = None
262261
self._transport = None
263262

264263
def data_received(self, data):

PythonLib/full/asyncio/tasks.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -809,7 +809,8 @@ def shield(arg):
809809
810810
The statement
811811
812-
res = await shield(something())
812+
task = asyncio.create_task(something())
813+
res = await shield(task)
813814
814815
is exactly equivalent to the statement
815816
@@ -825,10 +826,16 @@ def shield(arg):
825826
If you want to completely ignore cancellation (not recommended)
826827
you can combine shield() with a try/except clause, as follows:
827828
829+
task = asyncio.create_task(something())
828830
try:
829-
res = await shield(something())
831+
res = await shield(task)
830832
except CancelledError:
831833
res = None
834+
835+
Save a reference to tasks passed to this function, to avoid
836+
a task disappearing mid-execution. The event loop only keeps
837+
weak references to tasks. A task that isn't referenced elsewhere
838+
may get garbage collected at any time, even before it's done.
832839
"""
833840
inner = _ensure_future(arg)
834841
if inner.done():

PythonLib/full/asyncio/unix_events.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,8 @@ async def _make_subprocess_transport(self, protocol, args, shell,
223223
return transp
224224

225225
def _child_watcher_callback(self, pid, returncode, transp):
226-
self.call_soon_threadsafe(transp._process_exited, returncode)
226+
# Skip one iteration for callbacks to be executed
227+
self.call_soon_threadsafe(self.call_soon, transp._process_exited, returncode)
227228

228229
async def create_unix_connection(
229230
self, protocol_factory, path=None, *,

PythonLib/full/codeop.py

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -56,22 +56,22 @@ def _maybe_compile(compiler, source, filename, symbol):
5656
if symbol != "eval":
5757
source = "pass" # Replace it with a 'pass' statement
5858

59-
try:
60-
return compiler(source, filename, symbol)
61-
except SyntaxError: # Let other compile() errors propagate.
62-
pass
63-
64-
# Catch syntax warnings after the first compile
65-
# to emit warnings (SyntaxWarning, DeprecationWarning) at most once.
59+
# Disable compiler warnings when checking for incomplete input.
6660
with warnings.catch_warnings():
67-
warnings.simplefilter("error")
68-
61+
warnings.simplefilter("ignore", (SyntaxWarning, DeprecationWarning))
6962
try:
70-
compiler(source + "\n", filename, symbol)
71-
except SyntaxError as e:
72-
if "incomplete input" in str(e):
63+
compiler(source, filename, symbol)
64+
except SyntaxError: # Let other compile() errors propagate.
65+
try:
66+
compiler(source + "\n", filename, symbol)
7367
return None
74-
raise
68+
except SyntaxError as e:
69+
if "incomplete input" in str(e):
70+
return None
71+
# fallthrough
72+
73+
return compiler(source, filename, symbol)
74+
7575

7676
def _is_syntax_error(err1, err2):
7777
rep1 = repr(err1)

PythonLib/full/http/cookiejar.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1990,7 +1990,7 @@ class MozillaCookieJar(FileCookieJar):
19901990
19911991
This class differs from CookieJar only in the format it uses to save and
19921992
load cookies to and from a file. This class uses the Mozilla/Netscape
1993-
`cookies.txt' format. lynx uses this file format, too.
1993+
`cookies.txt' format. curl and lynx use this file format, too.
19941994
19951995
Don't expect cookies saved while the browser is running to be noticed by
19961996
the browser (in fact, Mozilla on unix will overwrite your saved cookies if

0 commit comments

Comments
 (0)