Skip to content

Commit 284ea3e

Browse files
committed
Merge remote-tracking branch 'upstream/main'
2 parents 6e07f97 + 983efcf commit 284ea3e

38 files changed

+523
-143
lines changed

Doc/library/dis.rst

+4-3
Original file line numberDiff line numberDiff line change
@@ -336,9 +336,10 @@ operation is being performed, so the intermediate analysis object isn't useful:
336336
Added the *show_caches* and *adaptive* parameters.
337337

338338
.. versionchanged:: 3.13
339-
The *show_caches* parameter is deprecated and has no effect. The *cache_info*
340-
field of each instruction is populated regardless of its value.
341-
339+
The *show_caches* parameter is deprecated and has no effect. The iterator
340+
generates the :class:`Instruction` instances with the *cache_info*
341+
field populated (regardless of the value of *show_caches*) and it no longer
342+
generates separate items for the cache entries.
342343

343344
.. function:: findlinestarts(code)
344345

Doc/library/symtable.rst

+4
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,10 @@ Examining Symbol Tables
151151

152152
Return ``True`` if the symbol is a parameter.
153153

154+
.. method:: is_type_parameter()
155+
156+
Return ``True`` if the symbol is a type parameter.
157+
154158
.. method:: is_global()
155159

156160
Return ``True`` if the symbol is global.

Doc/library/time.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -617,7 +617,7 @@ Functions
617617
- range [1, 12]
618618

619619
* - 2
620-
- .. attribute:: tm_day
620+
- .. attribute:: tm_mday
621621
- range [1, 31]
622622

623623
* - 3

Doc/library/zipfile.rst

+2-2
Original file line numberDiff line numberDiff line change
@@ -591,8 +591,8 @@ Path objects are traversable using the ``/`` operator or ``joinpath``.
591591

592592
.. versionadded:: 3.12
593593

594-
.. versionchanged:: 3.12.4
595-
Prior to 3.12.4, ``is_symlink`` would unconditionally return ``False``.
594+
.. versionchanged:: 3.13
595+
Previously, ``is_symlink`` would unconditionally return ``False``.
596596

597597
.. method:: Path.exists()
598598

Doc/reference/expressions.rst

+17-7
Original file line numberDiff line numberDiff line change
@@ -1211,7 +1211,8 @@ Raising ``0.0`` to a negative power results in a :exc:`ZeroDivisionError`.
12111211
Raising a negative number to a fractional power results in a :class:`complex`
12121212
number. (In earlier versions it raised a :exc:`ValueError`.)
12131213

1214-
This operation can be customized using the special :meth:`~object.__pow__` method.
1214+
This operation can be customized using the special :meth:`~object.__pow__` and
1215+
:meth:`~object.__rpow__` methods.
12151216

12161217
.. _unary:
12171218

@@ -1299,6 +1300,9 @@ This operation can be customized using the special :meth:`~object.__mul__` and
12991300
The ``@`` (at) operator is intended to be used for matrix multiplication. No
13001301
builtin Python types implement this operator.
13011302

1303+
This operation can be customized using the special :meth:`~object.__matmul__` and
1304+
:meth:`~object.__rmatmul__` methods.
1305+
13021306
.. versionadded:: 3.5
13031307

13041308
.. index::
@@ -1314,8 +1318,10 @@ integer; the result is that of mathematical division with the 'floor' function
13141318
applied to the result. Division by zero raises the :exc:`ZeroDivisionError`
13151319
exception.
13161320

1317-
This operation can be customized using the special :meth:`~object.__truediv__` and
1318-
:meth:`~object.__floordiv__` methods.
1321+
The division operation can be customized using the special :meth:`~object.__truediv__`
1322+
and :meth:`~object.__rtruediv__` methods.
1323+
The floor division operation can be customized using the special
1324+
:meth:`~object.__floordiv__` and :meth:`~object.__rfloordiv__` methods.
13191325

13201326
.. index::
13211327
single: modulo
@@ -1340,7 +1346,8 @@ also overloaded by string objects to perform old-style string formatting (also
13401346
known as interpolation). The syntax for string formatting is described in the
13411347
Python Library Reference, section :ref:`old-string-formatting`.
13421348

1343-
The *modulo* operation can be customized using the special :meth:`~object.__mod__` method.
1349+
The *modulo* operation can be customized using the special :meth:`~object.__mod__`
1350+
and :meth:`~object.__rmod__` methods.
13441351

13451352
The floor division operator, the modulo operator, and the :func:`divmod`
13461353
function are not defined for complex numbers. Instead, convert to a floating
@@ -1367,7 +1374,8 @@ This operation can be customized using the special :meth:`~object.__add__` and
13671374
The ``-`` (subtraction) operator yields the difference of its arguments. The
13681375
numeric arguments are first converted to a common type.
13691376

1370-
This operation can be customized using the special :meth:`~object.__sub__` method.
1377+
This operation can be customized using the special :meth:`~object.__sub__` and
1378+
:meth:`~object.__rsub__` methods.
13711379

13721380

13731381
.. _shifting:
@@ -1388,8 +1396,10 @@ The shifting operations have lower priority than the arithmetic operations:
13881396
These operators accept integers as arguments. They shift the first argument to
13891397
the left or right by the number of bits given by the second argument.
13901398

1391-
This operation can be customized using the special :meth:`~object.__lshift__` and
1392-
:meth:`~object.__rshift__` methods.
1399+
The left shift operation can be customized using the special :meth:`~object.__lshift__`
1400+
and :meth:`~object.__rlshift__` methods.
1401+
The right shift operation can be customized using the special :meth:`~object.__rshift__`
1402+
and :meth:`~object.__rrshift__` methods.
13931403

13941404
.. index:: pair: exception; ValueError
13951405

Doc/whatsnew/3.13.rst

+8-1
Original file line numberDiff line numberDiff line change
@@ -706,6 +706,13 @@ dis
706706
the ``show_offsets`` parameter.
707707
(Contributed by Irit Katriel in :gh:`112137`.)
708708

709+
* :meth:`~dis.get_instructions` no longer represents cache entries as
710+
separate instructions. Instead, it returns them as part of the
711+
:class:`~dis.Instruction`, in the new *cache_info* field. The
712+
*show_caches* argument to :meth:`~dis.get_instructions` is
713+
deprecated and no longer has any effect.
714+
(Contributed by Irit Katriel in :gh:`112962`.)
715+
709716
.. _whatsnew313-doctest:
710717

711718
doctest
@@ -1006,7 +1013,7 @@ random
10061013
------
10071014

10081015
* Add a :ref:`command-line interface <random-cli>`.
1009-
(Contributed by Hugo van Kemenade in :gh:`54321`.)
1016+
(Contributed by Hugo van Kemenade in :gh:`118131`.)
10101017

10111018
re
10121019
--

Include/internal/pycore_mimalloc.h

+1
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ struct _mimalloc_thread_state {
5252
mi_heap_t *current_object_heap;
5353
mi_heap_t heaps[_Py_MIMALLOC_HEAP_COUNT];
5454
mi_tld_t tld;
55+
int initialized;
5556
struct llist_node page_list;
5657
};
5758
#endif

Lib/_pyrepl/commands.py

+3
Original file line numberDiff line numberDiff line change
@@ -216,11 +216,14 @@ def do(self) -> None:
216216
import signal
217217

218218
self.reader.console.finish()
219+
self.reader.finish()
219220
os.kill(os.getpid(), signal.SIGINT)
220221

221222

222223
class ctrl_c(Command):
223224
def do(self) -> None:
225+
self.reader.console.finish()
226+
self.reader.finish()
224227
raise KeyboardInterrupt
225228

226229

Lib/_pyrepl/completing_reader.py

+15-8
Original file line numberDiff line numberDiff line change
@@ -187,18 +187,20 @@ def do(self) -> None:
187187
if p:
188188
r.insert(p)
189189
if last_is_completer:
190-
if not r.cmpltn_menu_visible:
191-
r.cmpltn_menu_visible = True
190+
r.cmpltn_menu_visible = True
191+
r.cmpltn_message_visible = False
192192
r.cmpltn_menu, r.cmpltn_menu_end = build_menu(
193193
r.console, completions, r.cmpltn_menu_end,
194194
r.use_brackets, r.sort_in_column)
195195
r.dirty = True
196-
elif stem + p in completions:
197-
r.msg = "[ complete but not unique ]"
198-
r.dirty = True
199-
else:
200-
r.msg = "[ not unique ]"
201-
r.dirty = True
196+
elif not r.cmpltn_menu_visible:
197+
r.cmpltn_message_visible = True
198+
if stem + p in completions:
199+
r.msg = "[ complete but not unique ]"
200+
r.dirty = True
201+
else:
202+
r.msg = "[ not unique ]"
203+
r.dirty = True
202204

203205

204206
class self_insert(commands.self_insert):
@@ -208,6 +210,9 @@ def do(self) -> None:
208210

209211
commands.self_insert.do(self)
210212

213+
if r.cmpltn_menu_visible or r.cmpltn_message_visible:
214+
r.calc_screen = r.calc_complete_screen
215+
211216
if r.cmpltn_menu_visible:
212217
stem = r.get_stem()
213218
if len(stem) < 1:
@@ -236,6 +241,7 @@ class CompletingReader(Reader):
236241
### Instance variables
237242
cmpltn_menu: list[str] = field(init=False)
238243
cmpltn_menu_visible: bool = field(init=False)
244+
cmpltn_message_visible: bool = field(init=False)
239245
cmpltn_menu_end: int = field(init=False)
240246
cmpltn_menu_choices: list[str] = field(init=False)
241247

@@ -271,6 +277,7 @@ def finish(self) -> None:
271277
def cmpltn_reset(self) -> None:
272278
self.cmpltn_menu = []
273279
self.cmpltn_menu_visible = False
280+
self.cmpltn_message_visible = False
274281
self.cmpltn_menu_end = 0
275282
self.cmpltn_menu_choices = []
276283

Lib/_pyrepl/console.py

+10-2
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333

3434
if TYPE_CHECKING:
3535
from typing import IO
36+
from typing import Callable
3637

3738

3839
@dataclass
@@ -134,8 +135,15 @@ def getpending(self) -> Event:
134135
...
135136

136137
@abstractmethod
137-
def wait(self) -> None:
138-
"""Wait for an event."""
138+
def wait(self, timeout: float | None) -> bool:
139+
"""Wait for an event. The return value is True if an event is
140+
available, False if the timeout has been reached. If timeout is
141+
None, wait forever. The timeout is in milliseconds."""
142+
...
143+
144+
@property
145+
def input_hook(self) -> Callable[[], int] | None:
146+
"""Returns the current input hook."""
139147
...
140148

141149
@abstractmethod

Lib/_pyrepl/reader.py

+9-1
Original file line numberDiff line numberDiff line change
@@ -650,7 +650,15 @@ def handle1(self, block: bool = True) -> bool:
650650
self.dirty = True
651651

652652
while True:
653-
event = self.console.get_event(block)
653+
input_hook = self.console.input_hook
654+
if input_hook:
655+
input_hook()
656+
# We use the same timeout as in readline.c: 100ms
657+
while not self.console.wait(100):
658+
input_hook()
659+
event = self.console.get_event(block=False)
660+
else:
661+
event = self.console.get_event(block)
654662
if not event: # can only happen if we're not blocking
655663
return False
656664

Lib/_pyrepl/simple_interact.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ def more_lines(unicodetext: str) -> bool:
149149
assert not more
150150
input_n += 1
151151
except KeyboardInterrupt:
152-
console.write("\nKeyboardInterrupt\n")
152+
console.write("KeyboardInterrupt\n")
153153
console.resetbuffer()
154154
except MemoryError:
155155
console.write("\nMemoryError\n")

Lib/_pyrepl/unix_console.py

+17-5
Original file line numberDiff line numberDiff line change
@@ -118,9 +118,12 @@ def __init__(self):
118118

119119
def register(self, fd, flag):
120120
self.fd = fd
121-
122-
def poll(self): # note: a 'timeout' argument would be *milliseconds*
123-
r, w, e = select.select([self.fd], [], [])
121+
# note: The 'timeout' argument is received as *milliseconds*
122+
def poll(self, timeout: float | None = None) -> list[int]:
123+
if timeout is None:
124+
r, w, e = select.select([self.fd], [], [])
125+
else:
126+
r, w, e = select.select([self.fd], [], [], timeout/1000)
124127
return r
125128

126129
poll = MinimalPoll # type: ignore[assignment]
@@ -385,11 +388,11 @@ def get_event(self, block: bool = True) -> Event | None:
385388
break
386389
return self.event_queue.get()
387390

388-
def wait(self):
391+
def wait(self, timeout: float | None = None) -> bool:
389392
"""
390393
Wait for events on the console.
391394
"""
392-
self.pollob.poll()
395+
return bool(self.pollob.poll(timeout))
393396

394397
def set_cursor_vis(self, visible):
395398
"""
@@ -527,6 +530,15 @@ def clear(self):
527530
self.__posxy = 0, 0
528531
self.screen = []
529532

533+
@property
534+
def input_hook(self):
535+
try:
536+
import posix
537+
except ImportError:
538+
return None
539+
if posix._is_inputhook_installed():
540+
return posix._inputhook
541+
530542
def __enable_bracketed_paste(self) -> None:
531543
os.write(self.output_fd, b"\x1b[?2004h")
532544

Lib/_pyrepl/windows_console.py

+20-2
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
from multiprocessing import Value
2424
import os
2525
import sys
26+
import time
27+
import msvcrt
2628

2729
from abc import ABC, abstractmethod
2830
from collections import deque
@@ -202,6 +204,15 @@ def refresh(self, screen: list[str], c_xy: tuple[int, int]) -> None:
202204
self.screen = screen
203205
self.move_cursor(cx, cy)
204206

207+
@property
208+
def input_hook(self):
209+
try:
210+
import nt
211+
except ImportError:
212+
return None
213+
if nt._is_inputhook_installed():
214+
return nt._inputhook
215+
205216
def __write_changed_line(
206217
self, y: int, oldline: str, newline: str, px_coord: int
207218
) -> None:
@@ -460,9 +471,16 @@ def getpending(self) -> Event:
460471
processed."""
461472
return Event("key", "", b"")
462473

463-
def wait(self) -> None:
474+
def wait(self, timeout: float | None) -> bool:
464475
"""Wait for an event."""
465-
raise NotImplementedError("No wait support")
476+
# Poor man's Windows select loop
477+
start_time = time.time()
478+
while True:
479+
if msvcrt.kbhit(): # type: ignore[attr-defined]
480+
return True
481+
if timeout and time.time() - start_time > timeout:
482+
return False
483+
time.sleep(0.01)
466484

467485
def repaint(self) -> None:
468486
raise NotImplementedError("No repaint support")

Lib/logging/config.py

+13-9
Original file line numberDiff line numberDiff line change
@@ -725,16 +725,16 @@ def add_filters(self, filterer, filters):
725725

726726
def _configure_queue_handler(self, klass, **kwargs):
727727
if 'queue' in kwargs:
728-
q = kwargs['queue']
728+
q = kwargs.pop('queue')
729729
else:
730730
q = queue.Queue() # unbounded
731-
rhl = kwargs.get('respect_handler_level', False)
732-
if 'listener' in kwargs:
733-
lklass = kwargs['listener']
734-
else:
735-
lklass = logging.handlers.QueueListener
736-
listener = lklass(q, *kwargs.get('handlers', []), respect_handler_level=rhl)
737-
handler = klass(q)
731+
732+
rhl = kwargs.pop('respect_handler_level', False)
733+
lklass = kwargs.pop('listener', logging.handlers.QueueListener)
734+
handlers = kwargs.pop('handlers', [])
735+
736+
listener = lklass(q, *handlers, respect_handler_level=rhl)
737+
handler = klass(q, **kwargs)
738738
handler.listener = listener
739739
return handler
740740

@@ -781,8 +781,12 @@ def configure_handler(self, config):
781781
# raise ValueError('No handlers specified for a QueueHandler')
782782
if 'queue' in config:
783783
from multiprocessing.queues import Queue as MPQueue
784+
from multiprocessing import Manager as MM
785+
proxy_queue = MM().Queue()
786+
proxy_joinable_queue = MM().JoinableQueue()
784787
qspec = config['queue']
785-
if not isinstance(qspec, (queue.Queue, MPQueue)):
788+
if not isinstance(qspec, (queue.Queue, MPQueue,
789+
type(proxy_queue), type(proxy_joinable_queue))):
786790
if isinstance(qspec, str):
787791
q = self.resolve(qspec)
788792
if not callable(q):

0 commit comments

Comments
 (0)