Skip to content

Commit dea00ba

Browse files
Merge branch 'main' into tk87tests
2 parents 19232e7 + d50a7c4 commit dea00ba

28 files changed

+166
-155
lines changed

.github/CODEOWNERS

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ Python/bytecodes.c @markshannon
4040
Python/optimizer*.c @markshannon
4141
Python/optimizer_analysis.c @Fidget-Spinner
4242
Python/optimizer_bytecodes.c @Fidget-Spinner
43+
Python/symtable.c @JelleZijlstra @carljm
4344
Lib/_pyrepl/* @pablogsal @lysnikolaou @ambv
4445
Lib/test/test_patma.py @brandtbucher
4546
Lib/test/test_type_*.py @JelleZijlstra
@@ -153,10 +154,10 @@ Include/internal/pycore_time.h @pganssle @abalkin
153154
/Tools/cases_generator/ @markshannon
154155

155156
# AST
156-
Python/ast.c @isidentical
157-
Parser/asdl.py @isidentical
158-
Parser/asdl_c.py @isidentical
159-
Lib/ast.py @isidentical
157+
Python/ast.c @isidentical @JelleZijlstra
158+
Parser/asdl.py @isidentical @JelleZijlstra
159+
Parser/asdl_c.py @isidentical @JelleZijlstra
160+
Lib/ast.py @isidentical @JelleZijlstra
160161

161162
# Mock
162163
/Lib/unittest/mock.py @cjw296

.github/workflows/build.yml

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -199,8 +199,9 @@ jobs:
199199
uses: ./.github/workflows/reusable-macos.yml
200200
with:
201201
config_hash: ${{ needs.check_source.outputs.config_hash }}
202-
# Cirrus is M1, macos-13 is default GHA Intel
203-
os-matrix: '["ghcr.io/cirruslabs/macos-runner:sonoma", "macos-13"]'
202+
# Cirrus and macos-14 are M1, macos-13 is default GHA Intel.
203+
# Cirrus used for upstream, macos-14 for forks.
204+
os-matrix: '["ghcr.io/cirruslabs/macos-runner:sonoma", "macos-14", "macos-13"]'
204205

205206
build_macos_free_threading:
206207
name: 'macOS (free-threading)'
@@ -210,8 +211,9 @@ jobs:
210211
with:
211212
config_hash: ${{ needs.check_source.outputs.config_hash }}
212213
free-threading: true
213-
# Cirrus is M1
214-
os-matrix: '["ghcr.io/cirruslabs/macos-runner:sonoma"]'
214+
# Cirrus and macos-14 are M1.
215+
# Cirrus used for upstream, macos-14 for forks.
216+
os-matrix: '["ghcr.io/cirruslabs/macos-runner:sonoma", "macos-14"]'
215217

216218
build_ubuntu:
217219
name: 'Ubuntu'

.github/workflows/reusable-macos.yml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ on:
1414

1515
jobs:
1616
build_macos:
17-
name: 'build and test'
17+
name: build and test (${{ matrix.os }})
1818
timeout-minutes: 60
1919
env:
2020
HOMEBREW_NO_ANALYTICS: 1
@@ -27,6 +27,13 @@ jobs:
2727
fail-fast: false
2828
matrix:
2929
os: ${{fromJson(inputs.os-matrix)}}
30+
is-fork:
31+
- ${{ github.repository_owner != 'python' }}
32+
exclude:
33+
- os: "ghcr.io/cirruslabs/macos-runner:sonoma"
34+
is-fork: true
35+
- os: "macos-14"
36+
is-fork: false
3037
runs-on: ${{ matrix.os }}
3138
steps:
3239
- uses: actions/checkout@v4

Doc/library/contextlib.rst

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,9 @@ Functions and classes provided:
314314

315315
If the code within the :keyword:`!with` block raises a
316316
:exc:`BaseExceptionGroup`, suppressed exceptions are removed from the
317-
group. If any exceptions in the group are not suppressed, a group containing them is re-raised.
317+
group. Any exceptions of the group which are not suppressed are re-raised in
318+
a new group which is created using the original group's :meth:`~BaseExceptionGroup.derive`
319+
method.
318320

319321
.. versionadded:: 3.4
320322

Doc/library/dis.rst

Lines changed: 4 additions & 3 deletions
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/exceptions.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -989,7 +989,8 @@ their subgroups based on the types of the contained exceptions.
989989
Returns an exception group with the same :attr:`message`, but which
990990
wraps the exceptions in ``excs``.
991991

992-
This method is used by :meth:`subgroup` and :meth:`split`. A
992+
This method is used by :meth:`subgroup` and :meth:`split`, which
993+
are used in various contexts to break up an exception group. A
993994
subclass needs to override it in order to make :meth:`subgroup`
994995
and :meth:`split` return instances of the subclass rather
995996
than :exc:`ExceptionGroup`.

Doc/library/ipaddress.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -990,7 +990,7 @@ The module also provides the following module level functions:
990990
.. function:: collapse_addresses(addresses)
991991

992992
Return an iterator of the collapsed :class:`IPv4Network` or
993-
:class:`IPv6Network` objects. *addresses* is an iterator of
993+
:class:`IPv6Network` objects. *addresses* is an :term:`iterable` of
994994
:class:`IPv4Network` or :class:`IPv6Network` objects. A :exc:`TypeError` is
995995
raised if *addresses* contains mixed version objects.
996996

Doc/library/time.rst

Lines changed: 1 addition & 1 deletion
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/whatsnew/3.13.rst

Lines changed: 7 additions & 0 deletions
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

InternalDocs/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,4 @@ it is not, please report that through the
1414

1515
[Exception Handling](exception_handling.md)
1616

17+
[Adaptive Instruction Families](adaptive.md)

Python/adaptive.md renamed to InternalDocs/adaptive.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22

33
## Families of instructions
44

5-
The core part of PEP 659 (specializing adaptive interpreter) is the families
6-
of instructions that perform the adaptive specialization.
5+
The core part of [PEP 659](https://peps.python.org/pep-0659/)
6+
(specializing adaptive interpreter) is the families of
7+
instructions that perform the adaptive specialization.
78

89
A family of instructions has the following fundamental properties:
910

@@ -30,8 +31,9 @@ although these are not fundamental and may change:
3031

3132
## Example family
3233

33-
The `LOAD_GLOBAL` instruction (in Python/bytecodes.c) already has an adaptive
34-
family that serves as a relatively simple example.
34+
The `LOAD_GLOBAL` instruction (in
35+
[Python/bytecodes.c](https://github.com/python/cpython/blob/main/Python/bytecodes.c))
36+
already has an adaptive family that serves as a relatively simple example.
3537

3638
The `LOAD_GLOBAL` instruction performs adaptive specialization,
3739
calling `_Py_Specialize_LoadGlobal()` when the counter reaches zero.

InternalDocs/exception_handling.md

Lines changed: 16 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -67,14 +67,18 @@ handler located at label `L1`.
6767
Handling Exceptions
6868
-------------------
6969

70-
At runtime, when an exception occurs, the interpreter looks up
71-
the offset of the current instruction in the exception table. If
72-
it finds a handler, control flow transfers to it. Otherwise, the
70+
At runtime, when an exception occurs, the interpreter calls
71+
``get_exception_handler()`` in
72+
[Python/ceval.c](https://github.com/python/cpython/blob/main/Python/ceval.c)
73+
to look up the offset of the current instruction in the exception
74+
table. If it finds a handler, control flow transfers to it. Otherwise, the
7375
exception bubbles up to the caller, and the caller's frame is
7476
checked for a handler covering the `CALL` instruction. This
7577
repeats until a handler is found or the topmost frame is reached.
7678
If no handler is found, the program terminates. During unwinding,
77-
the traceback is constructed as each frame is added to it.
79+
the traceback is constructed as each frame is added to it by
80+
``PyTraceBack_Here()``, which is in
81+
[Python/traceback.c](https://github.com/python/cpython/blob/main/Python/traceback.c).
7882

7983
Along with the location of an exception handler, each entry of the
8084
exception table also contains the stack depth of the `try` instruction
@@ -169,33 +173,12 @@ which is then encoded as:
169173

170174
for a total of five bytes.
171175

176+
The code to construct the exception table is in ``assemble_exception_table()``
177+
in [Python/assemble.c](https://github.com/python/cpython/blob/main/Python/assemble.c).
172178

173-
Script to parse the exception table
174-
-----------------------------------
175-
176-
```
177-
def parse_varint(iterator):
178-
b = next(iterator)
179-
val = b & 63
180-
while b&64:
181-
val <<= 6
182-
b = next(iterator)
183-
val |= b&63
184-
return val
185-
```
186-
```
187-
def parse_exception_table(code):
188-
iterator = iter(code.co_exceptiontable)
189-
try:
190-
while True:
191-
start = parse_varint(iterator)*2
192-
length = parse_varint(iterator)*2
193-
end = start + length - 2 # Present as inclusive, not exclusive
194-
target = parse_varint(iterator)*2
195-
dl = parse_varint(iterator)
196-
depth = dl >> 1
197-
lasti = bool(dl&1)
198-
yield start, end, target, depth, lasti
199-
except StopIteration:
200-
return
201-
```
179+
The interpreter's function to lookup the table by instruction offset is
180+
``get_exception_handler()`` in
181+
[Python/ceval.c](https://github.com/python/cpython/blob/main/Python/ceval.c).
182+
The Python function ``_parse_exception_table()`` in
183+
[Lib/dis.py](https://github.com/python/cpython/blob/main/Lib/dis.py)
184+
returns the exception table content as a list of namedtuple instances.

Lib/_pyrepl/commands.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,11 +216,13 @@ 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()
224226
self.reader.finish()
225227
raise KeyboardInterrupt
226228

Lib/_pyrepl/simple_interact.py

Lines changed: 1 addition & 1 deletion
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/ipaddress.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,7 @@ def collapse_addresses(addresses):
310310
[IPv4Network('192.0.2.0/24')]
311311
312312
Args:
313-
addresses: An iterator of IPv4Network or IPv6Network objects.
313+
addresses: An iterable of IPv4Network or IPv6Network objects.
314314
315315
Returns:
316316
An iterator of the collapsed IPv(4|6)Network objects.

Lib/logging/config.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -783,8 +783,10 @@ def configure_handler(self, config):
783783
from multiprocessing.queues import Queue as MPQueue
784784
from multiprocessing import Manager as MM
785785
proxy_queue = MM().Queue()
786+
proxy_joinable_queue = MM().JoinableQueue()
786787
qspec = config['queue']
787-
if not isinstance(qspec, (queue.Queue, MPQueue, type(proxy_queue))):
788+
if not isinstance(qspec, (queue.Queue, MPQueue,
789+
type(proxy_queue), type(proxy_joinable_queue))):
788790
if isinstance(qspec, str):
789791
q = self.resolve(qspec)
790792
if not callable(q):

Lib/pathlib/_abc.py

Lines changed: 28 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@
1212
"""
1313

1414
import functools
15+
import posixpath
1516
from glob import _Globber, _no_recurse_symlinks
16-
from errno import ENOTDIR, ELOOP
1717
from stat import S_ISDIR, S_ISLNK, S_ISREG, S_ISSOCK, S_ISBLK, S_ISCHR, S_ISFIFO
1818

1919

@@ -696,65 +696,34 @@ def resolve(self, strict=False):
696696
"""
697697
if self._resolving:
698698
return self
699-
path_root, parts = self._stack
700-
path = self.with_segments(path_root)
701-
try:
702-
path = path.absolute()
703-
except UnsupportedOperation:
704-
path_tail = []
705-
else:
706-
path_root, path_tail = path._stack
707-
path_tail.reverse()
708-
709-
# If the user has *not* overridden the `readlink()` method, then symlinks are unsupported
710-
# and (in non-strict mode) we can improve performance by not calling `stat()`.
711-
querying = strict or getattr(self.readlink, '_supported', True)
712-
link_count = 0
713-
while parts:
714-
part = parts.pop()
715-
if not part or part == '.':
716-
continue
717-
if part == '..':
718-
if not path_tail:
719-
if path_root:
720-
# Delete '..' segment immediately following root
721-
continue
722-
elif path_tail[-1] != '..':
723-
# Delete '..' segment and its predecessor
724-
path_tail.pop()
725-
continue
726-
path_tail.append(part)
727-
if querying and part != '..':
728-
path = self.with_segments(path_root + self.parser.sep.join(path_tail))
699+
700+
def getcwd():
701+
return str(self.with_segments().absolute())
702+
703+
if strict or getattr(self.readlink, '_supported', True):
704+
def lstat(path_str):
705+
path = self.with_segments(path_str)
729706
path._resolving = True
730-
try:
731-
st = path.stat(follow_symlinks=False)
732-
if S_ISLNK(st.st_mode):
733-
# Like Linux and macOS, raise OSError(errno.ELOOP) if too many symlinks are
734-
# encountered during resolution.
735-
link_count += 1
736-
if link_count >= self._max_symlinks:
737-
raise OSError(ELOOP, "Too many symbolic links in path", self._raw_path)
738-
target_root, target_parts = path.readlink()._stack
739-
# If the symlink target is absolute (like '/etc/hosts'), set the current
740-
# path to its uppermost parent (like '/').
741-
if target_root:
742-
path_root = target_root
743-
path_tail.clear()
744-
else:
745-
path_tail.pop()
746-
# Add the symlink target's reversed tail parts (like ['hosts', 'etc']) to
747-
# the stack of unresolved path parts.
748-
parts.extend(target_parts)
749-
continue
750-
elif parts and not S_ISDIR(st.st_mode):
751-
raise NotADirectoryError(ENOTDIR, "Not a directory", self._raw_path)
752-
except OSError:
753-
if strict:
754-
raise
755-
else:
756-
querying = False
757-
return self.with_segments(path_root + self.parser.sep.join(path_tail))
707+
return path.lstat()
708+
709+
def readlink(path_str):
710+
path = self.with_segments(path_str)
711+
path._resolving = True
712+
return str(path.readlink())
713+
else:
714+
# If the user has *not* overridden the `readlink()` method, then
715+
# symlinks are unsupported and (in non-strict mode) we can improve
716+
# performance by not calling `path.lstat()`.
717+
def skip(path_str):
718+
# This exception will be internally consumed by `_realpath()`.
719+
raise OSError("Operation skipped.")
720+
721+
lstat = readlink = skip
722+
723+
return self.with_segments(posixpath._realpath(
724+
str(self), strict, self.parser.sep,
725+
getcwd=getcwd, lstat=lstat, readlink=readlink,
726+
maxlinks=self._max_symlinks))
758727

759728
def symlink_to(self, target, target_is_directory=False):
760729
"""

0 commit comments

Comments
 (0)