Skip to content

Commit f46024d

Browse files
authored
Merge branch 'main' into timeout-error-fix
2 parents 27cbe83 + d0ecbdd commit f46024d

30 files changed

+604
-426
lines changed

Doc/library/pdb.rst

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -179,13 +179,15 @@ slightly different way:
179179
.. versionadded:: 3.14
180180
The *commands* argument.
181181

182-
.. function:: post_mortem(traceback=None)
182+
.. function:: post_mortem(t=None)
183183

184-
Enter post-mortem debugging of the given *traceback* object. If no
185-
*traceback* is given, it uses the one of the exception that is currently
186-
being handled (an exception must be being handled if the default is to be
187-
used).
184+
Enter post-mortem debugging of the given exception or
185+
:ref:`traceback object <traceback-objects>`. If no value is given, it uses
186+
the exception that is currently being handled, or raises ``ValueError`` if
187+
there isn’t one.
188188

189+
.. versionchanged:: 3.13
190+
Support for exception objects was added.
189191

190192
.. function:: pm()
191193

Doc/library/sysconfig.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -388,7 +388,8 @@ Other functions
388388

389389
Windows will return one of:
390390

391-
- win-amd64 (64bit Windows on AMD64, aka x86_64, Intel64, and EM64T)
391+
- win-amd64 (64-bit Windows on AMD64, aka x86_64, Intel64, and EM64T)
392+
- win-arm64 (64-bit Windows on ARM64, aka AArch64)
392393
- win32 (all others - specifically, sys.platform is returned)
393394

394395
macOS can return:

Include/internal/pycore_emscripten_trampoline.h

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -27,24 +27,14 @@
2727

2828
#if defined(__EMSCRIPTEN__) && defined(PY_CALL_TRAMPOLINE)
2929

30-
void _Py_EmscriptenTrampoline_Init(_PyRuntimeState *runtime);
30+
void
31+
_Py_EmscriptenTrampoline_Init(_PyRuntimeState *runtime);
3132

3233
PyObject*
33-
_PyEM_TrampolineCall_JavaScript(PyCFunctionWithKeywords func,
34-
PyObject* self,
35-
PyObject* args,
36-
PyObject* kw);
37-
38-
PyObject*
39-
_PyEM_TrampolineCall_Reflection(PyCFunctionWithKeywords func,
40-
PyObject* self,
41-
PyObject* args,
42-
PyObject* kw);
43-
44-
#define _PyEM_TrampolineCall(meth, self, args, kw) \
45-
((_PyRuntime.wasm_type_reflection_available) ? \
46-
(_PyEM_TrampolineCall_Reflection((PyCFunctionWithKeywords)(meth), (self), (args), (kw))) : \
47-
(_PyEM_TrampolineCall_JavaScript((PyCFunctionWithKeywords)(meth), (self), (args), (kw))))
34+
_PyEM_TrampolineCall(PyCFunctionWithKeywords func,
35+
PyObject* self,
36+
PyObject* args,
37+
PyObject* kw);
4838

4939
#define _PyCFunction_TrampolineCall(meth, self, args) \
5040
_PyEM_TrampolineCall( \
@@ -62,8 +52,6 @@ _PyEM_TrampolineCall_Reflection(PyCFunctionWithKeywords func,
6252

6353
#else // defined(__EMSCRIPTEN__) && defined(PY_CALL_TRAMPOLINE)
6454

65-
#define _Py_EmscriptenTrampoline_Init(runtime)
66-
6755
#define _PyCFunction_TrampolineCall(meth, self, args) \
6856
(meth)((self), (args))
6957

Include/internal/pycore_freelist_state.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ extern "C" {
2222
# define Py_futureiters_MAXFREELIST 255
2323
# define Py_object_stack_chunks_MAXFREELIST 4
2424
# define Py_unicode_writers_MAXFREELIST 1
25+
# define Py_pymethodobjects_MAXFREELIST 20
2526

2627
// A generic freelist of either PyObjects or other data structures.
2728
struct _Py_freelist {
@@ -48,6 +49,7 @@ struct _Py_freelists {
4849
struct _Py_freelist futureiters;
4950
struct _Py_freelist object_stack_chunks;
5051
struct _Py_freelist unicode_writers;
52+
struct _Py_freelist pymethodobjects;
5153
};
5254

5355
#ifdef __cplusplus

Include/internal/pycore_runtime.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ typedef struct pyruntimestate {
172172
#if defined(__EMSCRIPTEN__) && defined(PY_CALL_TRAMPOLINE)
173173
// Used in "Python/emscripten_trampoline.c" to choose between type
174174
// reflection trampoline and EM_JS trampoline.
175-
bool wasm_type_reflection_available;
175+
int (*emscripten_count_args_function)(PyCFunctionWithKeywords func);
176176
#endif
177177

178178
/* All the objects that are shared by the runtime's interpreters. */

Lib/pathlib/_abc.py

Lines changed: 62 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
it's developed alongside pathlib. If it finds success and maturity as a PyPI
88
package, it could become a public part of the standard library.
99
10-
Two base classes are defined here -- PurePathBase and PathBase -- that
11-
resemble pathlib's PurePath and Path respectively.
10+
Three base classes are defined here -- JoinablePath, ReadablePath and
11+
WritablePath.
1212
"""
1313

1414
import functools
@@ -56,13 +56,13 @@ def concat_path(path, text):
5656
return path.with_segments(str(path) + text)
5757

5858

59-
class CopyWorker:
59+
class CopyReader:
6060
"""
6161
Class that implements copying between path objects. An instance of this
62-
class is available from the PathBase.copy property; it's made callable so
63-
that PathBase.copy() can be treated as a method.
62+
class is available from the ReadablePath.copy property; it's made callable
63+
so that ReadablePath.copy() can be treated as a method.
6464
65-
The target path's CopyWorker drives the process from its _create() method.
65+
The target path's CopyWriter drives the process from its _create() method.
6666
Files and directories are exchanged by calling methods on the source and
6767
target paths, and metadata is exchanged by calling
6868
source.copy._read_metadata() and target.copy._write_metadata().
@@ -77,11 +77,15 @@ def __call__(self, target, follow_symlinks=True, dirs_exist_ok=False,
7777
"""
7878
Recursively copy this file or directory tree to the given destination.
7979
"""
80-
if not isinstance(target, PathBase):
80+
if not isinstance(target, ReadablePath):
8181
target = self._path.with_segments(target)
8282

83-
# Delegate to the target path's CopyWorker object.
84-
return target.copy._create(self._path, follow_symlinks, dirs_exist_ok, preserve_metadata)
83+
# Delegate to the target path's CopyWriter object.
84+
try:
85+
create = target.copy._create
86+
except AttributeError:
87+
raise TypeError(f"Target is not writable: {target}") from None
88+
return create(self._path, follow_symlinks, dirs_exist_ok, preserve_metadata)
8589

8690
_readable_metakeys = frozenset()
8791

@@ -91,6 +95,10 @@ def _read_metadata(self, metakeys, *, follow_symlinks=True):
9195
"""
9296
raise NotImplementedError
9397

98+
99+
class CopyWriter(CopyReader):
100+
__slots__ = ()
101+
94102
_writable_metakeys = frozenset()
95103

96104
def _write_metadata(self, metadata, *, follow_symlinks=True):
@@ -182,7 +190,7 @@ def _ensure_distinct_path(self, source):
182190
raise err
183191

184192

185-
class PurePathBase:
193+
class JoinablePath:
186194
"""Base class for pure path objects.
187195
188196
This class *does not* provide several magic methods that are defined in
@@ -334,7 +342,7 @@ def match(self, path_pattern, *, case_sensitive=None):
334342
is matched. The recursive wildcard '**' is *not* supported by this
335343
method.
336344
"""
337-
if not isinstance(path_pattern, PurePathBase):
345+
if not isinstance(path_pattern, JoinablePath):
338346
path_pattern = self.with_segments(path_pattern)
339347
if case_sensitive is None:
340348
case_sensitive = _is_case_sensitive(self.parser)
@@ -359,7 +367,7 @@ def full_match(self, pattern, *, case_sensitive=None):
359367
Return True if this path matches the given glob-style pattern. The
360368
pattern is matched against the entire path.
361369
"""
362-
if not isinstance(pattern, PurePathBase):
370+
if not isinstance(pattern, JoinablePath):
363371
pattern = self.with_segments(pattern)
364372
if case_sensitive is None:
365373
case_sensitive = _is_case_sensitive(self.parser)
@@ -369,7 +377,7 @@ def full_match(self, pattern, *, case_sensitive=None):
369377

370378

371379

372-
class PathBase(PurePathBase):
380+
class ReadablePath(JoinablePath):
373381
"""Base class for concrete path objects.
374382
375383
This class provides dummy implementations for many methods that derived
@@ -434,25 +442,6 @@ def read_text(self, encoding=None, errors=None, newline=None):
434442
with self.open(mode='r', encoding=encoding, errors=errors, newline=newline) as f:
435443
return f.read()
436444

437-
def write_bytes(self, data):
438-
"""
439-
Open the file in bytes mode, write to it, and close the file.
440-
"""
441-
# type-check for the buffer interface before truncating the file
442-
view = memoryview(data)
443-
with self.open(mode='wb') as f:
444-
return f.write(view)
445-
446-
def write_text(self, data, encoding=None, errors=None, newline=None):
447-
"""
448-
Open the file in text mode, write to it, and close the file.
449-
"""
450-
if not isinstance(data, str):
451-
raise TypeError('data must be str, not %s' %
452-
data.__class__.__name__)
453-
with self.open(mode='w', encoding=encoding, errors=errors, newline=newline) as f:
454-
return f.write(data)
455-
456445
def _scandir(self):
457446
"""Yield os.DirEntry-like objects of the directory contents.
458447
@@ -474,7 +463,7 @@ def glob(self, pattern, *, case_sensitive=None, recurse_symlinks=True):
474463
"""Iterate over this subtree and yield all existing files (of any
475464
kind, including directories) matching the given relative pattern.
476465
"""
477-
if not isinstance(pattern, PurePathBase):
466+
if not isinstance(pattern, JoinablePath):
478467
pattern = self.with_segments(pattern)
479468
anchor, parts = _explode_path(pattern)
480469
if anchor:
@@ -496,7 +485,7 @@ def rglob(self, pattern, *, case_sensitive=None, recurse_symlinks=True):
496485
directories) matching the given relative pattern, anywhere in
497486
this subtree.
498487
"""
499-
if not isinstance(pattern, PurePathBase):
488+
if not isinstance(pattern, JoinablePath):
500489
pattern = self.with_segments(pattern)
501490
pattern = '**' / pattern
502491
return self.glob(pattern, case_sensitive=case_sensitive, recurse_symlinks=recurse_symlinks)
@@ -543,6 +532,28 @@ def readlink(self):
543532
"""
544533
raise NotImplementedError
545534

535+
copy = property(CopyReader, doc=CopyReader.__call__.__doc__)
536+
537+
def copy_into(self, target_dir, *, follow_symlinks=True,
538+
dirs_exist_ok=False, preserve_metadata=False):
539+
"""
540+
Copy this file or directory tree into the given existing directory.
541+
"""
542+
name = self.name
543+
if not name:
544+
raise ValueError(f"{self!r} has an empty name")
545+
elif isinstance(target_dir, ReadablePath):
546+
target = target_dir / name
547+
else:
548+
target = self.with_segments(target_dir, name)
549+
return self.copy(target, follow_symlinks=follow_symlinks,
550+
dirs_exist_ok=dirs_exist_ok,
551+
preserve_metadata=preserve_metadata)
552+
553+
554+
class WritablePath(ReadablePath):
555+
__slots__ = ()
556+
546557
def symlink_to(self, target, target_is_directory=False):
547558
"""
548559
Make this path a symlink pointing to the target path.
@@ -556,20 +567,23 @@ def mkdir(self, mode=0o777, parents=False, exist_ok=False):
556567
"""
557568
raise NotImplementedError
558569

559-
copy = property(CopyWorker, doc=CopyWorker.__call__.__doc__)
570+
def write_bytes(self, data):
571+
"""
572+
Open the file in bytes mode, write to it, and close the file.
573+
"""
574+
# type-check for the buffer interface before truncating the file
575+
view = memoryview(data)
576+
with self.open(mode='wb') as f:
577+
return f.write(view)
560578

561-
def copy_into(self, target_dir, *, follow_symlinks=True,
562-
dirs_exist_ok=False, preserve_metadata=False):
579+
def write_text(self, data, encoding=None, errors=None, newline=None):
563580
"""
564-
Copy this file or directory tree into the given existing directory.
581+
Open the file in text mode, write to it, and close the file.
565582
"""
566-
name = self.name
567-
if not name:
568-
raise ValueError(f"{self!r} has an empty name")
569-
elif isinstance(target_dir, PathBase):
570-
target = target_dir / name
571-
else:
572-
target = self.with_segments(target_dir, name)
573-
return self.copy(target, follow_symlinks=follow_symlinks,
574-
dirs_exist_ok=dirs_exist_ok,
575-
preserve_metadata=preserve_metadata)
583+
if not isinstance(data, str):
584+
raise TypeError('data must be str, not %s' %
585+
data.__class__.__name__)
586+
with self.open(mode='w', encoding=encoding, errors=errors, newline=newline) as f:
587+
return f.write(data)
588+
589+
copy = property(CopyWriter, doc=CopyWriter.__call__.__doc__)

0 commit comments

Comments
 (0)